Fix the noalias checking so that it doesn't worry about
authorDan Gohman <gohman@apple.com>
Tue, 1 Jun 2010 20:51:40 +0000 (20:51 +0000)
committerDan Gohman <gohman@apple.com>
Tue, 1 Jun 2010 20:51:40 +0000 (20:51 +0000)
an argument aliasing itself. Thanks Duncan!

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

lib/Analysis/Lint.cpp

index 1e836af1c5ca5cb4e921a3d053e475bce6af37b9..6c137333d6daed1a1df7aaff7940c1b08193b785 100644 (file)
@@ -215,7 +215,6 @@ void Lint::visitCallSite(CallSite CS) {
 
     const FunctionType *FT = F->getFunctionType();
     unsigned NumActualArgs = unsigned(CS.arg_end()-CS.arg_begin());
-    std::vector<Value *> NoAliasVals;
 
     Assert1(FT->isVarArg() ?
               FT->getNumParams() <= NumActualArgs :
@@ -233,8 +232,19 @@ void Lint::visitCallSite(CallSite CS) {
         Assert1(Formal->getType() == Actual->getType(),
                 "Undefined behavior: Call argument type mismatches "
                 "callee parameter type", &I);
+
+        // Check that noalias arguments don't alias other arguments. The
+        // AliasAnalysis API isn't expressive enough for what we really want
+        // to do. Known partial overlap is not distinguished from the case
+        // where nothing is known.
         if (Formal->hasNoAliasAttr() && Actual->getType()->isPointerTy())
-          NoAliasVals.push_back(Actual);
+          for (CallSite::arg_iterator BI = CS.arg_begin(); BI != AE; ++BI) {
+            Assert1(AI == BI ||
+                    AA->alias(*AI, ~0u, *BI, ~0u) != AliasAnalysis::MustAlias,
+                    "Unusual: noalias argument aliases another argument", &I);
+          }
+
+        // Check that an sret argument points to valid memory.
         if (Formal->hasStructRetAttr() && Actual->getType()->isPointerTy()) {
           const Type *Ty =
             cast<PointerType>(Formal->getType())->getElementType();
@@ -244,16 +254,6 @@ void Lint::visitCallSite(CallSite CS) {
         }
       }
     }
-
-    // Check that the noalias arguments don't overlap. The AliasAnalysis API
-    // isn't expressive enough for what we really want to do. Known partial
-    // overlap is not distinguished from the case where nothing is known.
-    for (CallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end();
-         AI != AE; ++AI)
-      for (std::vector<Value *>::iterator J = NoAliasVals.begin(),
-           E = NoAliasVals.end(); J != E; ++J)
-        Assert1(AA->alias(*J, ~0u, *AI, ~0u) != AliasAnalysis::MustAlias,
-                "Unusual: noalias argument aliases another argument", &I);
   }
 
   if (CS.isCall() && cast<CallInst>(CS.getInstruction())->isTailCall())