[llvm-commits] CVS: llvm/lib/Analysis/BasicAliasAnalysis.cpp

Chris Lattner lattner at cs.uiuc.edu
Fri Mar 3 18:06:46 PST 2006



Changes in directory llvm/lib/Analysis:

BasicAliasAnalysis.cpp updated: 1.76 -> 1.77
---
Log message:

Be more conservative with our symbolic alias analysis.  In particular,
don't assume that A[1][0] and A[0][i] can't alias.  "i" might be out of
range, or even negative.  This fixes a miscompilation of 188.ammp (which
does bad pointer tricks) with the new CFE.

Testcase here: Analysis/BasicAA/2006-03-03-BadArraySubscript.ll


---
Diffs of the changes:  (+35 -6)

 BasicAliasAnalysis.cpp |   41 +++++++++++++++++++++++++++++++++++------
 1 files changed, 35 insertions(+), 6 deletions(-)


Index: llvm/lib/Analysis/BasicAliasAnalysis.cpp
diff -u llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.76 llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.77
--- llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.76	Fri Jan 13 19:25:24 2006
+++ llvm/lib/Analysis/BasicAliasAnalysis.cpp	Fri Mar  3 20:06:34 2006
@@ -527,6 +527,14 @@
   // chain.  For example:
   //        A[i][0] != A[j][1] iff (&A[0][1]-&A[0][0] >= std::max(G1S, G2S))
   //
+  // We have to be careful here about array accesses.  In particular, consider:
+  //        A[1][0] vs A[0][i]
+  // In this case, we don't *know* that the array will be accessed in bounds:
+  // the index could even be negative.  Because of this, we have to
+  // conservatively *give up* and return may alias.  We disregard differing
+  // array subscripts that are followed by a variable index without going
+  // through a struct.
+  //
   unsigned SizeMax = std::max(G1S, G2S);
   if (SizeMax == ~0U) return MayAlias; // Avoid frivolous work.
 
@@ -547,15 +555,36 @@
             GEP1Ops[FirstConstantOper] = G1OC;
             GEP2Ops[FirstConstantOper] = G2OC;
           }
-
+          
           if (G1OC != G2OC) {
+            // Handle the "be careful" case above: if this is an array
+            // subscript, scan for a subsequent variable array index.
+            if (isa<ArrayType>(BasePtr1Ty))  {
+              const Type *NextTy =cast<ArrayType>(BasePtr1Ty)->getElementType();
+              bool isBadCase = false;
+              
+              for (unsigned Idx = FirstConstantOper+1;
+                   Idx != MinOperands && isa<ArrayType>(NextTy); ++Idx) {
+                const Value *V1 = GEP1Ops[Idx], *V2 = GEP2Ops[Idx];
+                if (!isa<Constant>(V1) || !isa<Constant>(V2)) {
+                  isBadCase = true;
+                  break;
+                }
+                NextTy = cast<ArrayType>(NextTy)->getElementType();
+              }
+              
+              if (isBadCase) G1OC = 0;
+            }
+
             // Make sure they are comparable (ie, not constant expressions), and
             // make sure the GEP with the smaller leading constant is GEP1.
-            Constant *Compare = ConstantExpr::getSetGT(G1OC, G2OC);
-            if (ConstantBool *CV = dyn_cast<ConstantBool>(Compare)) {
-              if (CV->getValue())   // If they are comparable and G2 > G1
-                std::swap(GEP1Ops, GEP2Ops);  // Make GEP1 < GEP2
-              break;
+            if (G1OC) {
+              Constant *Compare = ConstantExpr::getSetGT(G1OC, G2OC);
+              if (ConstantBool *CV = dyn_cast<ConstantBool>(Compare)) {
+                if (CV->getValue())   // If they are comparable and G2 > G1
+                  std::swap(GEP1Ops, GEP2Ops);  // Make GEP1 < GEP2
+                break;
+              }
             }
           }
         }






More information about the llvm-commits mailing list