summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-03-04 02:06:34 +0000
committerChris Lattner <sabre@nondot.org>2006-03-04 02:06:34 +0000
commit071faf25e03be1ba3af1fdf2a387528a3bfa70ae (patch)
tree134dd50675c45e787d24e891531401da30cc0d14 /llvm/lib
parent05285fbf5bad382c74aeba89eb0e0218ca67a2dd (diff)
downloadbcm5719-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
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Analysis/BasicAliasAnalysis.cpp41
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;
+ }
}
}
}
OpenPOWER on IntegriCloud