mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-19 01:27:40 +00:00
Implement PR1143 (at -m64) by making basicaa look through extensions. We
previously already handled it at -m32 because there were no i32->i64 extensions for addressing. llvm-svn: 89959
This commit is contained in:
parent
a403a7eddc
commit
ce573daf09
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user