[llvm-commits] [llvm] r60820 - in /llvm/trunk: lib/Analysis/BasicAliasAnalysis.cpp test/Analysis/BasicAA/2008-12-09-GEP-IndicesAlias.ll

Chris Lattner sabre at nondot.org
Tue Dec 9 17:04:49 PST 2008


Author: lattner
Date: Tue Dec  9 19:04:47 2008
New Revision: 60820

URL: http://llvm.org/viewvc/llvm-project?rev=60820&view=rev
Log:
Allow basicaa to walk through geps with identical indices in 
parallel, allowing it to decide that P/Q must alias if A/B
must alias in things like:
 P = gep A, 0, i, 1
 Q = gep B, 0, i, 1

This allows GVN to delete 62 more instructions out of 403.gcc.


Added:
    llvm/trunk/test/Analysis/BasicAA/2008-12-09-GEP-IndicesAlias.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=60820&r1=60819&r2=60820&view=diff

==============================================================================
--- llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp (original)
+++ llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp Tue Dec  9 19:04:47 2008
@@ -85,7 +85,7 @@
 }
 
 static const Value *GetGEPOperands(const Value *V, 
-                                   SmallVector<Value*, 16> &GEPOps){
+                                   SmallVector<Value*, 16> &GEPOps) {
   assert(GEPOps.empty() && "Expect empty list to populate!");
   GEPOps.insert(GEPOps.end(), cast<User>(V)->op_begin()+1,
                 cast<User>(V)->op_end());
@@ -369,8 +369,7 @@
 
 
 // alias - Provide a bunch of ad-hoc rules to disambiguate in common cases, such
-// as array references.  Note that this function is heavily tail recursive.
-// Hopefully we have a smart C++ compiler.  :)
+// as array references.
 //
 AliasAnalysis::AliasResult
 BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size,
@@ -389,13 +388,14 @@
   if (!isa<PointerType>(V1->getType()) || !isa<PointerType>(V2->getType()))
     return NoAlias;  // Scalars cannot alias each other
 
-  // Strip off cast instructions...
+  // Strip off cast instructions.   Since V1 and V2 are pointers, they must be
+  // pointer<->pointer bitcasts.
   if (const BitCastInst *I = dyn_cast<BitCastInst>(V1))
     return alias(I->getOperand(0), V1Size, V2, V2Size);
   if (const BitCastInst *I = dyn_cast<BitCastInst>(V2))
     return alias(V1, V1Size, I->getOperand(0), V2Size);
 
-  // Figure out what objects these things are pointing to if we can...
+  // Figure out what objects these things are pointing to if we can.
   const Value *O1 = V1->getUnderlyingObject();
   const Value *O2 = V2->getUnderlyingObject();
 
@@ -438,21 +438,35 @@
   // constant expression getelementptrs here.
   //
   if (isGEP(V1) && isGEP(V2)) {
+    const User *GEP1 = cast<User>(V1);
+    const User *GEP2 = cast<User>(V2);
+    
+    // If V1 and V2 are identical GEPs, just recurse down on both of them.
+    // This allows us to analyze things like:
+    //   P = gep A, 0, i, 1
+    //   Q = gep B, 0, i, 1
+    // by just analyzing A and B.  This is even safe for variable indices.
+    if (GEP1->getType() == GEP2->getType() &&
+        GEP1->getNumOperands() == GEP2->getNumOperands() &&
+        GEP1->getOperand(0)->getType() == GEP2->getOperand(0)->getType() &&
+        // All operands are the same, ignoring the base.
+        std::equal(GEP1->op_begin()+1, GEP1->op_end(), GEP2->op_begin()+1))
+      return alias(GEP1->getOperand(0), V1Size, GEP2->getOperand(0), V2Size);
+    
+    
     // Drill down into the first non-gep value, to test for must-aliasing of
     // the base pointers.
-    const User *G = cast<User>(V1);
-    while (isGEP(G->getOperand(0)) &&
-           G->getOperand(1) ==
-           Constant::getNullValue(G->getOperand(1)->getType()))
-      G = cast<User>(G->getOperand(0));
-    const Value *BasePtr1 = G->getOperand(0);
-
-    G = cast<User>(V2);
-    while (isGEP(G->getOperand(0)) &&
-           G->getOperand(1) ==
-           Constant::getNullValue(G->getOperand(1)->getType()))
-      G = cast<User>(G->getOperand(0));
-    const Value *BasePtr2 = G->getOperand(0);
+    while (isGEP(GEP1->getOperand(0)) &&
+           GEP1->getOperand(1) ==
+           Constant::getNullValue(GEP1->getOperand(1)->getType()))
+      GEP1 = cast<User>(GEP1->getOperand(0));
+    const Value *BasePtr1 = GEP1->getOperand(0);
+
+    while (isGEP(GEP2->getOperand(0)) &&
+           GEP2->getOperand(1) ==
+           Constant::getNullValue(GEP2->getOperand(1)->getType()))
+      GEP2 = cast<User>(GEP2->getOperand(0));
+    const Value *BasePtr2 = GEP2->getOperand(0);
 
     // Do the base pointers alias?
     AliasResult BaseAlias = alias(BasePtr1, ~0U, BasePtr2, ~0U);

Added: llvm/trunk/test/Analysis/BasicAA/2008-12-09-GEP-IndicesAlias.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/BasicAA/2008-12-09-GEP-IndicesAlias.ll?rev=60820&view=auto

==============================================================================
--- llvm/trunk/test/Analysis/BasicAA/2008-12-09-GEP-IndicesAlias.ll (added)
+++ llvm/trunk/test/Analysis/BasicAA/2008-12-09-GEP-IndicesAlias.ll Tue Dec  9 19:04:47 2008
@@ -0,0 +1,16 @@
+; RUN: llvm-as < %s | opt -aa-eval -print-all-alias-modref-info -disable-output |& grep {MustAlias:.*%R,.*%r}
+; Make sure that basicaa thinks R and r are must aliases.
+
+define i32 @test(i8 * %P) {
+entry:
+	%Q = bitcast i8* %P to {i32, i32}*
+	%R = getelementptr {i32, i32}* %Q, i32 0, i32 1
+	%S = load i32* %R
+
+	%q = bitcast i8* %P to {i32, i32}*
+	%r = getelementptr {i32, i32}* %q, i32 0, i32 1
+	%s = load i32* %r
+
+	%t = sub i32 %S, %s
+	ret i32 %t
+}





More information about the llvm-commits mailing list