[llvm-commits] [llvm] r84079 - in /llvm/trunk: lib/Analysis/BasicAliasAnalysis.cpp test/Analysis/BasicAA/2009-10-13-GEP-BaseNoAlias.ll
Evan Cheng
evan.cheng at apple.com
Tue Oct 13 23:41:49 PDT 2009
Author: evancheng
Date: Wed Oct 14 01:41:49 2009
New Revision: 84079
URL: http://llvm.org/viewvc/llvm-project?rev=84079&view=rev
Log:
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.
Added:
llvm/trunk/test/Analysis/BasicAA/2009-10-13-GEP-BaseNoAlias.ll
Modified:
llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp
Modified: llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp?rev=84079&r1=84078&r2=84079&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp (original)
+++ llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp Wed Oct 14 01:41:49 2009
@@ -428,49 +428,54 @@
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());
+ // 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;
- }
+ if (Offset >= (int64_t)V2Size || Offset <= -(int64_t)V1Size)
+ return NoAlias;
}
}
@@ -492,7 +497,9 @@
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);
Added: llvm/trunk/test/Analysis/BasicAA/2009-10-13-GEP-BaseNoAlias.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/BasicAA/2009-10-13-GEP-BaseNoAlias.ll?rev=84079&view=auto
==============================================================================
--- llvm/trunk/test/Analysis/BasicAA/2009-10-13-GEP-BaseNoAlias.ll (added)
+++ llvm/trunk/test/Analysis/BasicAA/2009-10-13-GEP-BaseNoAlias.ll Wed Oct 14 01:41:49 2009
@@ -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
+
+ at Y = common global i32 0
+ at 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
+}
More information about the llvm-commits
mailing list