diff options
author | Chris Lattner <sabre@nondot.org> | 2006-03-04 02:06:34 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2006-03-04 02:06:34 +0000 |
commit | 071faf25e03be1ba3af1fdf2a387528a3bfa70ae (patch) | |
tree | 134dd50675c45e787d24e891531401da30cc0d14 | |
parent | 05285fbf5bad382c74aeba89eb0e0218ca67a2dd (diff) | |
download | bcm5719-llvm-071faf25e03be1ba3af1fdf2a387528a3bfa70ae.tar.gz bcm5719-llvm-071faf25e03be1ba3af1fdf2a387528a3bfa70ae.zip |
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
llvm-svn: 26515
-rw-r--r-- | llvm/lib/Analysis/BasicAliasAnalysis.cpp | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp index 71bcbd2cf09..f10691e531f 100644 --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -527,6 +527,14 @@ CheckGEPInstructions(const Type* BasePtr1Ty, std::vector<Value*> &GEP1Ops, // 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 @@ CheckGEPInstructions(const Type* BasePtr1Ty, std::vector<Value*> &GEP1Ops, 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; + } } } } |