aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/BasicAliasAnalysis.cpp
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
commit681a33e26dd3222477f13520b94e7417bff59e32 (patch)
tree94120d4b2c105d4906c5973a76d59f2d9b7b23db /lib/Analysis/BasicAliasAnalysis.cpp
parentdf199f11c669b70389553329d582fb7cef86e3b6 (diff)
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
Diffstat (limited to 'lib/Analysis/BasicAliasAnalysis.cpp')
-rw-r--r--lib/Analysis/BasicAliasAnalysis.cpp85
1 files changed, 46 insertions, 39 deletions
diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp
index ea1f893980..ce1d8773ef 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);