[OperandBundles] Teach AliasAnalysis about operand bundles
authorSanjoy Das <sanjoy@playingwithpointers.com>
Thu, 22 Oct 2015 03:12:51 +0000 (03:12 +0000)
committerSanjoy Das <sanjoy@playingwithpointers.com>
Thu, 22 Oct 2015 03:12:51 +0000 (03:12 +0000)
Summary:
If a `CallSite` has operand bundles, then do not peek into the called
function to get a more precise `ModRef` answer.

This is tested using `argmemonly`, `-basicaa` and `-gvn`; but the
functionality is not specific to any of these.

Depends on D13961

Reviewers: reames, chandlerc

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D13962

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@250974 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/AliasAnalysis.h
include/llvm/IR/InstrTypes.h
test/Feature/OperandBundles/basic-aa-argmemonly.ll [new file with mode: 0644]

index 781ab25b391973ffe2e5f976e99aca3e69888436..2f4722fb964648f6b12e3db1788f66478355e563 100644 (file)
@@ -759,8 +759,12 @@ public:
   }
 
   FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) {
-    if (const Function *F = CS.getCalledFunction())
-      return getBestAAResults().getModRefBehavior(F);
+    if (!CS.hasOperandBundles())
+      // If CS has operand bundles then aliasing attributes from the function it
+      // calls do not directly apply to the CallSite.  This can be made more
+      // precise in the future.
+      if (const Function *F = CS.getCalledFunction())
+        return getBestAAResults().getModRefBehavior(F);
 
     return FMRB_UnknownModRefBehavior;
   }
index 136a6c3f457ad058cbd1aedfcb7e59b0951a49f4..207b5b42d50fa014210cb55a24537f006c2150d1 100644 (file)
@@ -1255,8 +1255,8 @@ protected:
   /// \brief Is the function attribute S disallowed by some operand bundle on
   /// this operand bundle user?
   bool isFnAttrDisallowedByOpBundle(StringRef S) const {
-    // Operand bundles only possibly disallow readnone and readonly attributes.
-    // All String attributes are fine.
+    // Operand bundles only possibly disallow readnone, readonly and argmenonly
+    // attributes.  All String attributes are fine.
     return false;
   }
 
@@ -1267,6 +1267,9 @@ protected:
     default:
       return false;
 
+    case Attribute::ArgMemOnly:
+      return hasReadingOperandBundles();
+
     case Attribute::ReadNone:
       return hasReadingOperandBundles();
 
diff --git a/test/Feature/OperandBundles/basic-aa-argmemonly.ll b/test/Feature/OperandBundles/basic-aa-argmemonly.ll
new file mode 100644 (file)
index 0000000..1f3b378
--- /dev/null
@@ -0,0 +1,28 @@
+; RUN: opt -S -basicaa -gvn < %s | FileCheck %s
+
+declare void @argmemonly_function(i32 *) argmemonly
+
+define i32 @test0(i32* %P, i32* noalias %P2) {
+; CHECK-LABEL: @test0(
+  %v1 = load i32, i32* %P
+; CHECK: %v1 = load i32, i32* %P
+  call void @argmemonly_function(i32* %P2) [ "tag"() ]
+; CHECK: call void @argmemonly_function(
+  %v2 = load i32, i32* %P
+; CHECK: %v2 = load i32, i32* %P
+  %diff = sub i32 %v1, %v2
+; CHECK: %diff = sub i32 %v1, %v2
+  ret i32 %diff
+; CHECK: ret i32 %diff
+}
+
+define i32 @test1(i32* %P, i32* noalias %P2) {
+; CHECK-LABEL: @test1(
+  %v1 = load i32, i32* %P
+  call void @argmemonly_function(i32* %P2) argmemonly [ "tag"() ]
+; CHECK: call void @argmemonly_function(
+  %v2 = load i32, i32* %P
+  %diff = sub i32 %v1, %v2
+  ret i32 %diff
+; CHECK: ret i32 0
+}