aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2009-10-14 06:41:49 +0000
committerEvan Cheng <evan.cheng@apple.com>2009-10-14 06:41:49 +0000
commit9d17125f7a6ac8eb8e679b1fd7c14a0b539d15f9 (patch)
tree94120d4b2c105d4906c5973a76d59f2d9b7b23db
parent8e004f69769d7fc77faabbb9f67a3e6600c6d1f1 (diff)
downloadexternal_llvm-9d17125f7a6ac8eb8e679b1fd7c14a0b539d15f9.zip
external_llvm-9d17125f7a6ac8eb8e679b1fd7c14a0b539d15f9.tar.gz
external_llvm-9d17125f7a6ac8eb8e679b1fd7c14a0b539d15f9.tar.bz2
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@84079 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Analysis/BasicAliasAnalysis.cpp85
-rw-r--r--test/Analysis/BasicAA/2009-10-13-GEP-BaseNoAlias.ll30
2 files changed, 76 insertions, 39 deletions
diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp
index ea1f893..ce1d877 100644
--- a/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/lib/Analysis/BasicAliasAnalysis.cpp
@@ -428,49 +428,54 @@ BasicAliasAnalysis::aliasGEP(const Value *V1, unsigned V1Size,
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());
-
- if (Offset >= (int64_t)V2Size || Offset <= -(int64_t)V1Size)
- 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());
+
+ if (Offset >= (int64_t)V2Size || Offset <= -(int64_t)V1Size)
+ return NoAlias;
}
}
@@ -492,7 +497,9 @@ BasicAliasAnalysis::aliasPHI(const PHINode *PN, unsigned PNSize,
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);
diff --git a/test/Analysis/BasicAA/2009-10-13-GEP-BaseNoAlias.ll b/test/Analysis/BasicAA/2009-10-13-GEP-BaseNoAlias.ll
new file mode 100644
index 0000000..771636f
--- /dev/null
+++ b/test/Analysis/BasicAA/2009-10-13-GEP-BaseNoAlias.ll
@@ -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
+
+@Y = common global i32 0
+@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
+}