Make BasicAliasAnalysis recognize the fact a noalias argument cannot alias another...
authorMichael Kuperstein <michael.m.kuperstein@intel.com>
Tue, 28 May 2013 08:17:48 +0000 (08:17 +0000)
committerMichael Kuperstein <michael.m.kuperstein@intel.com>
Tue, 28 May 2013 08:17:48 +0000 (08:17 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182755 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/AliasAnalysis.h
lib/Analysis/AliasAnalysis.cpp
lib/Analysis/BasicAliasAnalysis.cpp
test/Analysis/BasicAA/noalias-param.ll [new file with mode: 0644]

index d703f21c021c66dc731ba9f1d6db1420649b5431..efafbbdb776134efc0ed959d2b7b82e49050b129 100644 (file)
@@ -584,6 +584,10 @@ struct DenseMapInfo<AliasAnalysis::Location> {
 /// function.
 bool isNoAliasCall(const Value *V);
 
 /// function.
 bool isNoAliasCall(const Value *V);
 
+/// isNoAliasArgument - Return true if this is an argument with the noalias
+/// attribute.
+bool isNoAliasArgument(const Value *V);
+
 /// isIdentifiedObject - Return true if this pointer refers to a distinct and
 /// identifiable object.  This returns true for:
 ///    Global Variables and Functions (but not Global Aliases)
 /// isIdentifiedObject - Return true if this pointer refers to a distinct and
 /// identifiable object.  This returns true for:
 ///    Global Variables and Functions (but not Global Aliases)
index 210b80ab63ef7b2a1f5b89d79ac6d1e38ea841b2..3454ce0be2b9db3cdbf2035257860cce7bd11de8 100644 (file)
@@ -537,6 +537,15 @@ bool llvm::isNoAliasCall(const Value *V) {
   return false;
 }
 
   return false;
 }
 
+/// isNoAliasArgument - Return true if this is an argument with the noalias
+/// attribute.
+bool llvm::isNoAliasArgument(const Value *V)
+{
+  if (const Argument *A = dyn_cast<Argument>(V))
+    return A->hasNoAliasAttr();
+  return false;
+}
+
 /// isIdentifiedObject - Return true if this pointer refers to a distinct and
 /// identifiable object.  This returns true for:
 ///    Global Variables and Functions (but not Global Aliases)
 /// isIdentifiedObject - Return true if this pointer refers to a distinct and
 /// identifiable object.  This returns true for:
 ///    Global Variables and Functions (but not Global Aliases)
index f8509dd070ff0f6bcceb77e350c4b51e0f187730..f20e83e9113cdc6cf0c84e10bbc1ca3a5dd4e058 100644 (file)
@@ -142,6 +142,17 @@ static bool isObjectSize(const Value *V, uint64_t Size,
   return ObjectSize != AliasAnalysis::UnknownSize && ObjectSize == Size;
 }
 
   return ObjectSize != AliasAnalysis::UnknownSize && ObjectSize == Size;
 }
 
+/// isIdentifiedFunctionLocal - Return true if V is umabigously identified
+/// at the function-level. Different IdentifiedFunctionLocals can't alias.
+/// Further, an IdentifiedFunctionLocal can not alias with any function
+/// arguments other than itself, which is not neccessarily true for
+/// IdentifiedObjects.
+static bool isIdentifiedFunctionLocal(const Value *V)
+{
+  return isa<AllocaInst>(V) || isNoAliasCall(V) || isNoAliasArgument(V);
+}
+
+
 //===----------------------------------------------------------------------===//
 // GetElementPtr Instruction Decomposition and Analysis
 //===----------------------------------------------------------------------===//
 //===----------------------------------------------------------------------===//
 // GetElementPtr Instruction Decomposition and Analysis
 //===----------------------------------------------------------------------===//
@@ -1205,10 +1216,10 @@ BasicAliasAnalysis::aliasCheck(const Value *V1, uint64_t V1Size,
         (isa<Constant>(O2) && isIdentifiedObject(O1) && !isa<Constant>(O1)))
       return NoAlias;
 
         (isa<Constant>(O2) && isIdentifiedObject(O1) && !isa<Constant>(O1)))
       return NoAlias;
 
-    // Arguments can't alias with local allocations or noalias calls
-    // in the same function.
-    if (((isa<Argument>(O1) && (isa<AllocaInst>(O2) || isNoAliasCall(O2))) ||
-         (isa<Argument>(O2) && (isa<AllocaInst>(O1) || isNoAliasCall(O1)))))
+    // Function arguments can't alias with things that are known to be
+    // unambigously identified at the function level.
+    if ((isa<Argument>(O1) && isIdentifiedFunctionLocal(O2)) ||
+        (isa<Argument>(O2) && isIdentifiedFunctionLocal(O1)))
       return NoAlias;
 
     // Most objects can't alias null.
       return NoAlias;
 
     // Most objects can't alias null.
diff --git a/test/Analysis/BasicAA/noalias-param.ll b/test/Analysis/BasicAA/noalias-param.ll
new file mode 100644 (file)
index 0000000..6494771
--- /dev/null
@@ -0,0 +1,23 @@
+; RUN: opt < %s -basicaa -aa-eval -print-all-alias-modref-info 2>&1 | FileCheck %s
+
+declare i32* @captures(i32* %cap) nounwind readonly
+
+define void @no(i32* noalias %a, i32* %b) nounwind {
+entry:
+  store i32 1, i32* %a 
+  %cap = call i32* @captures(i32* %a) nounwind readonly
+  %l = load i32* %b
+  ret void
+}
+
+; CHECK: NoAlias:      i32* %a, i32* %b
+
+define void @yes(i32* %c, i32* %d) nounwind {
+entry:
+  store i32 1, i32* %c 
+  %cap = call i32* @captures(i32* %c) nounwind readonly
+  %l = load i32* %d
+  ret void
+}
+
+; CHECK: MayAlias:     i32* %c, i32* %d