diff options
-rw-r--r-- | include/llvm/Analysis/ValueTracking.h | 6 | ||||
-rw-r--r-- | lib/Analysis/ValueTracking.cpp | 25 | ||||
-rw-r--r-- | test/Analysis/BasicAA/gep-alias.ll | 17 |
3 files changed, 45 insertions, 3 deletions
diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h index 0596891..5f3c671 100644 --- a/include/llvm/Analysis/ValueTracking.h +++ b/include/llvm/Analysis/ValueTracking.h @@ -82,6 +82,12 @@ namespace llvm { /// it into a base pointer with a constant offset and a number of scaled /// symbolic offsets. /// + /// The scaled symbolic offsets (represented by pairs of a Value* and a scale + /// in the VarIndices vector) are Value*'s that are known to be scaled by the + /// specified amount, but which may have other unrepresented high bits. As + /// such, the gep cannot necessarily be reconstructed from its decomposed + /// form. + /// /// When TargetData is around, this function is capable of analyzing /// everything that Value::getUnderlyingObject() can look through. When not, /// it just looks through pointer casts. diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp index 5439bbf..f6a492f 100644 --- a/lib/Analysis/ValueTracking.cpp +++ b/lib/Analysis/ValueTracking.cpp @@ -950,8 +950,10 @@ bool llvm::CannotBeNegativeZero(const Value *V, unsigned Depth) { /// GetLinearExpression - Analyze the specified value as a linear expression: -/// "A*V + B". Return the scale and offset values as APInts and return V as a -/// Value*. The incoming Value is known to be a scalar integer. +/// "A*V + B", where A and B are constant integers. Return the scale and offset +/// values as APInts and return V as a Value*. The incoming Value is known to +/// have IntegerType. Note that this looks through extends, so the high bits +/// may not be represented in the result. static Value *GetLinearExpression(Value *V, APInt &Scale, APInt &Offset, const TargetData *TD) { assert(isa<IntegerType>(V->getType()) && "Not an integer value"); @@ -984,6 +986,20 @@ static Value *GetLinearExpression(Value *V, APInt &Scale, APInt &Offset, } } + // Since clients don't care about the high bits of the value, just scales and + // offsets, we can look through extensions. + if (isa<SExtInst>(V) || isa<ZExtInst>(V)) { + Value *CastOp = cast<CastInst>(V)->getOperand(0); + unsigned OldWidth = Scale.getBitWidth(); + unsigned SmallWidth = CastOp->getType()->getPrimitiveSizeInBits(); + Scale.trunc(SmallWidth); + Offset.trunc(SmallWidth); + Value *Result = GetLinearExpression(CastOp, Scale, Offset, TD); + Scale.zext(OldWidth); + Offset.zext(OldWidth); + return Result; + } + Scale = 1; Offset = 0; return V; @@ -993,6 +1009,11 @@ static Value *GetLinearExpression(Value *V, APInt &Scale, APInt &Offset, /// into a base pointer with a constant offset and a number of scaled symbolic /// offsets. /// +/// The scaled symbolic offsets (represented by pairs of a Value* and a scale in +/// the VarIndices vector) are Value*'s that are known to be scaled by the +/// specified amount, but which may have other unrepresented high bits. As such, +/// the gep cannot necessarily be reconstructed from its decomposed form. +/// /// When TargetData is around, this function is capable of analyzing everything /// that Value::getUnderlyingObject() can look through. When not, it just looks /// through pointer casts. diff --git a/test/Analysis/BasicAA/gep-alias.ll b/test/Analysis/BasicAA/gep-alias.ll index 68722fb..0eb8bb0 100644 --- a/test/Analysis/BasicAA/gep-alias.ll +++ b/test/Analysis/BasicAA/gep-alias.ll @@ -115,4 +115,19 @@ define i32 @test7(i32* %p, i64 %i) { ; CHECK: ret i32 0 } - +; P[zext(i)] != p[zext(i+1)] +; PR1143 +define i32 @test8(i32* %p, i32 %i) { + %i1 = zext i32 %i to i64 + %pi = getelementptr i32* %p, i64 %i1 + %i.next = add i32 %i, 1 + %i.next2 = zext i32 %i.next to i64 + %pi.next = getelementptr i32* %p, i64 %i.next2 + %x = load i32* %pi + store i32 42, i32* %pi.next + %y = load i32* %pi + %z = sub i32 %x, %y + ret i32 %z +; CHECK: @test8 +; CHECK: ret i32 0 +} |