[llvm-commits] [llvm] r84079 - in /llvm/trunk: lib/Analysis/BasicAliasAnalysis.cpp test/Analysis/BasicAA/2009-10-13-GEP-BaseNoAlias.ll

Evan Cheng evan.cheng at apple.com
Tue Oct 13 23:41:49 PDT 2009


Author: evancheng
Date: Wed Oct 14 01:41:49 2009
New Revision: 84079

URL: http://llvm.org/viewvc/llvm-project?rev=84079&view=rev
Log:
Another BasicAA fix. If a value does not alias a GEP's base pointer, then it
cannot alias the GEP. GEP pointer alias rule states this clearly:
A pointer value formed from a getelementptr instruction is associated with the
addresses associated with the first operand of the getelementptr.

Added:
    llvm/trunk/test/Analysis/BasicAA/2009-10-13-GEP-BaseNoAlias.ll
Modified:
    llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp

Modified: llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp?rev=84079&r1=84078&r2=84079&view=diff

==============================================================================
--- llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp (original)
+++ llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp Wed Oct 14 01:41:49 2009
@@ -428,49 +428,54 @@
   SmallVector<Value*, 16> GEPOperands;
   const Value *BasePtr = GetGEPOperands(V1, GEPOperands);
 
-  AliasResult R = aliasCheck(BasePtr, V1Size, V2, V2Size);
-  if (R == MustAlias) {
-    // If there is at least one non-zero constant index, we know they cannot
-    // alias.
-    bool ConstantFound = false;
-    bool AllZerosFound = true;
-    for (unsigned i = 0, e = GEPOperands.size(); i != e; ++i)
-      if (const Constant *C = dyn_cast<Constant>(GEPOperands[i])) {
-        if (!C->isNullValue()) {
-          ConstantFound = true;
-          AllZerosFound = false;
-          break;
-        }
-      } else {
+  AliasResult R = aliasCheck(BasePtr, ~0U, V2, V2Size);
+  if (R != MustAlias)
+    // If V2 may alias GEP base pointer, conservatively returns MayAlias.
+    // If V2 is known not to alias GEP base pointer, then the two values
+    // cannot alias per GEP semantics: "A pointer value formed from a
+    // getelementptr instruction is associated with the addresses associated
+    // with the first operand of the getelementptr".
+    return R;
+
+  // If there is at least one non-zero constant index, we know they cannot
+  // alias.
+  bool ConstantFound = false;
+  bool AllZerosFound = true;
+  for (unsigned i = 0, e = GEPOperands.size(); i != e; ++i)
+    if (const Constant *C = dyn_cast<Constant>(GEPOperands[i])) {
+      if (!C->isNullValue()) {
+        ConstantFound = true;
         AllZerosFound = false;
+        break;
       }
+    } else {
+      AllZerosFound = false;
+    }
 
-    // If we have getelementptr <ptr>, 0, 0, 0, 0, ... and V2 must aliases
-    // the ptr, the end result is a must alias also.
-    if (AllZerosFound)
-      return MustAlias;
+  // If we have getelementptr <ptr>, 0, 0, 0, 0, ... and V2 must aliases
+  // the ptr, the end result is a must alias also.
+  if (AllZerosFound)
+    return MustAlias;
 
-    if (ConstantFound) {
-      if (V2Size <= 1 && V1Size <= 1)  // Just pointer check?
-        return NoAlias;
+  if (ConstantFound) {
+    if (V2Size <= 1 && V1Size <= 1)  // Just pointer check?
+      return NoAlias;
 
-      // Otherwise we have to check to see that the distance is more than
-      // the size of the argument... build an index vector that is equal to
-      // the arguments provided, except substitute 0's for any variable
-      // indexes we find...
-      if (TD &&
-          cast<PointerType>(BasePtr->getType())->getElementType()->isSized()) {
-        for (unsigned i = 0; i != GEPOperands.size(); ++i)
-          if (!isa<ConstantInt>(GEPOperands[i]))
-            GEPOperands[i] = Constant::getNullValue(GEPOperands[i]->getType());
-        int64_t Offset =
-          TD->getIndexedOffset(BasePtr->getType(),
-                               &GEPOperands[0],
-                               GEPOperands.size());
+    // Otherwise we have to check to see that the distance is more than
+    // the size of the argument... build an index vector that is equal to
+    // the arguments provided, except substitute 0's for any variable
+    // indexes we find...
+    if (TD &&
+        cast<PointerType>(BasePtr->getType())->getElementType()->isSized()) {
+      for (unsigned i = 0; i != GEPOperands.size(); ++i)
+        if (!isa<ConstantInt>(GEPOperands[i]))
+          GEPOperands[i] = Constant::getNullValue(GEPOperands[i]->getType());
+      int64_t Offset = TD->getIndexedOffset(BasePtr->getType(),
+                                            &GEPOperands[0],
+                                            GEPOperands.size());
 
-        if (Offset >= (int64_t)V2Size || Offset <= -(int64_t)V1Size)
-          return NoAlias;
-      }
+      if (Offset >= (int64_t)V2Size || Offset <= -(int64_t)V1Size)
+        return NoAlias;
     }
   }
 
@@ -492,7 +497,9 @@
     Value *PV1 = PN->getIncomingValue(i);
     if (isa<PHINode>(PV1))
       // If any of the source itself is a PHI, return MayAlias conservatively
-      // to avoid compile time explosion.
+      // to avoid compile time explosion. The worst possible case is if both
+      // sides are PHI nodes. In which case, this is O(m x n) time where 'm'
+      // and 'n' are the number of PHI sources.
       return MayAlias;
     if (UniqueSrc.insert(PV1))
       V1Srcs.push_back(PV1);

Added: llvm/trunk/test/Analysis/BasicAA/2009-10-13-GEP-BaseNoAlias.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/BasicAA/2009-10-13-GEP-BaseNoAlias.ll?rev=84079&view=auto

==============================================================================
--- llvm/trunk/test/Analysis/BasicAA/2009-10-13-GEP-BaseNoAlias.ll (added)
+++ llvm/trunk/test/Analysis/BasicAA/2009-10-13-GEP-BaseNoAlias.ll Wed Oct 14 01:41:49 2009
@@ -0,0 +1,30 @@
+; RUN: opt < %s -aa-eval -print-all-alias-modref-info -disable-output |& grep {NoAlias:.*%P,.*@Z}
+; If GEP base doesn't alias Z, then GEP doesn't alias Z.
+; rdar://7282591
+
+ at Y = common global i32 0
+ at Z = common global i32 0
+
+define void @foo(i32 %cond) nounwind ssp {
+entry:
+  %a = alloca i32
+  %tmp = icmp ne i32 %cond, 0
+  br i1 %tmp, label %bb, label %bb1
+
+bb:
+  %b = getelementptr i32* %a, i32 0
+  br label %bb2
+
+bb1:
+  br label %bb2
+
+bb2:
+  %P = phi i32* [ %b, %bb ], [ @Y, %bb1 ]
+  %tmp1 = load i32* @Z, align 4
+  store i32 123, i32* %P, align 4
+  %tmp2 = load i32* @Z, align 4
+  br label %return
+
+return:
+  ret void
+}





More information about the llvm-commits mailing list