Teach BasicAA about noalias function parameters. Passes all of DejaGNU and test-suite.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@40624 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp
index 580f7e5..ffe7411 100644
--- a/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/lib/Analysis/BasicAliasAnalysis.cpp
@@ -18,6 +18,7 @@
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Function.h"
+#include "llvm/ParameterAttributes.h"
 #include "llvm/GlobalVariable.h"
 #include "llvm/Instructions.h"
 #include "llvm/Pass.h"
@@ -294,6 +295,21 @@
 
   // Pointing at a discernible object?
   if (O1) {
+    // Check for noalias attribute
+    if (isa<Argument>(O1)) {
+      const Argument *Arg = cast<Argument>(O1);
+      const Function *Func = Arg->getParent();
+      const ParamAttrsList *Attr = Func->getFunctionType()->getParamAttrs();
+      if (Attr) {
+        unsigned Idx = 1;
+        for (Function::const_arg_iterator I = Func->arg_begin(), 
+              E = Func->arg_end(); I != E; ++I, ++Idx) {
+          if (&(*I) == Arg && 
+               Attr->paramHasAttr(Idx, ParamAttr::NoAlias))
+            return NoAlias;
+        }
+      }
+    }
     if (O2) {
       if (isa<Argument>(O1)) {
         // Incoming argument cannot alias locally allocated object!
@@ -307,7 +323,22 @@
         // If they are two different objects, we know that we have no alias...
         return NoAlias;
       }
-
+      
+      // Check for noalias atrribute independently from above logic
+      if (isa<Argument>(O2)) {
+        const Argument *Arg = cast<Argument>(O2);
+        const Function *Func = Arg->getParent();
+        const ParamAttrsList *Attr = Func->getFunctionType()->getParamAttrs();
+        if (Attr) {
+          unsigned Idx = 1;
+          for (Function::const_arg_iterator I = Func->arg_begin(), 
+                E = Func->arg_end(); I != E; ++I, ++Idx) {
+            if (&(*I) == Arg && 
+                 Attr->paramHasAttr(Idx, ParamAttr::NoAlias))
+              return NoAlias;
+          }
+        }
+      }
       // If they are the same object, they we can look at the indexes.  If they
       // index off of the object is the same for both pointers, they must alias.
       // If they are provably different, they must not alias.  Otherwise, we
diff --git a/test/Analysis/BasicAA/2007-07-31-NoAliasTest.ll b/test/Analysis/BasicAA/2007-07-31-NoAliasTest.ll
new file mode 100644
index 0000000..f760de3
--- /dev/null
+++ b/test/Analysis/BasicAA/2007-07-31-NoAliasTest.ll
@@ -0,0 +1,12 @@
+; RUN:   llvm-as %s -o - | opt -aa-eval -print-may-aliases -disable-output |& grep '1 may alias'
+; RUN:   llvm-as %s -o - | opt -aa-eval -print-may-aliases -disable-output |& grep '5 no alias'
+; RUN:   llvm-as %s -o - | opt -aa-eval -print-may-aliases -disable-output |& grep 'MayAlias:     i32* %ptr4, i32* %ptr2'
+
+define void @_Z3fooPiS_RiS_(i32* noalias  %ptr1, i32* %ptr2, i32* noalias  %ptr3, i32* %ptr4) {
+entry:
+        store i32 0, i32* %ptr1
+        store i32 0, i32* %ptr2
+        store i32 0, i32* %ptr3
+        store i32 0, i32* %ptr4
+        ret void
+}
\ No newline at end of file