mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-23 02:29:18 +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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@89959 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b18004c13c
commit
1ce0eaa25f
@ -82,6 +82,12 @@ namespace llvm {
|
|||||||
/// it into a base pointer with a constant offset and a number of scaled
|
/// it into a base pointer with a constant offset and a number of scaled
|
||||||
/// symbolic offsets.
|
/// 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
|
/// When TargetData is around, this function is capable of analyzing
|
||||||
/// everything that Value::getUnderlyingObject() can look through. When not,
|
/// everything that Value::getUnderlyingObject() can look through. When not,
|
||||||
/// it just looks through pointer casts.
|
/// 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:
|
/// 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
|
/// "A*V + B", where A and B are constant integers. Return the scale and offset
|
||||||
/// Value*. The incoming Value is known to be a scalar integer.
|
/// 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,
|
static Value *GetLinearExpression(Value *V, APInt &Scale, APInt &Offset,
|
||||||
const TargetData *TD) {
|
const TargetData *TD) {
|
||||||
assert(isa<IntegerType>(V->getType()) && "Not an integer value");
|
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;
|
Scale = 1;
|
||||||
Offset = 0;
|
Offset = 0;
|
||||||
return V;
|
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
|
/// into a base pointer with a constant offset and a number of scaled symbolic
|
||||||
/// offsets.
|
/// 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
|
/// When TargetData is around, this function is capable of analyzing everything
|
||||||
/// that Value::getUnderlyingObject() can look through. When not, it just looks
|
/// that Value::getUnderlyingObject() can look through. When not, it just looks
|
||||||
/// through pointer casts.
|
/// through pointer casts.
|
||||||
|
@ -115,4 +115,19 @@ define i32 @test7(i32* %p, i64 %i) {
|
|||||||
; CHECK: ret i32 0
|
; 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