mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-08 21:32:39 +00:00
Teach X86FastISel to fold constant offsets and scaled indices in
the same address. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107373 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
28a173581c
commit
5c87bf64d6
@ -423,20 +423,29 @@ bool X86FastISel::X86SelectAddress(const Value *V, X86AddressMode &AM) {
|
||||
Disp += SL->getElementOffset(Idx);
|
||||
} else {
|
||||
uint64_t S = TD.getTypeAllocSize(GTI.getIndexedType());
|
||||
if (const ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
|
||||
// Constant-offset addressing.
|
||||
Disp += CI->getSExtValue() * S;
|
||||
} else if (IndexReg == 0 &&
|
||||
(!AM.GV || !Subtarget->isPICStyleRIPRel()) &&
|
||||
(S == 1 || S == 2 || S == 4 || S == 8)) {
|
||||
// Scaled-index addressing.
|
||||
Scale = S;
|
||||
IndexReg = getRegForGEPIndex(Op).first;
|
||||
if (IndexReg == 0)
|
||||
return false;
|
||||
} else
|
||||
// Unsupported.
|
||||
goto unsupported_gep;
|
||||
SmallVector<const Value *, 4> Worklist;
|
||||
Worklist.push_back(Op);
|
||||
do {
|
||||
Op = Worklist.pop_back_val();
|
||||
if (const ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
|
||||
// Constant-offset addressing.
|
||||
Disp += CI->getSExtValue() * S;
|
||||
} else if (IndexReg == 0 &&
|
||||
(!AM.GV || !Subtarget->isPICStyleRIPRel()) &&
|
||||
(S == 1 || S == 2 || S == 4 || S == 8)) {
|
||||
// Scaled-index addressing.
|
||||
Scale = S;
|
||||
IndexReg = getRegForGEPIndex(Op).first;
|
||||
if (IndexReg == 0)
|
||||
return false;
|
||||
} else if (const AddOperator *Add = dyn_cast<AddOperator>(Op)) {
|
||||
// An add. Try to fold both operands.
|
||||
Worklist.push_back(Add->getOperand(0));
|
||||
Worklist.push_back(Add->getOperand(1));
|
||||
} else
|
||||
// Unsupported.
|
||||
goto unsupported_gep;
|
||||
} while (!Worklist.empty());
|
||||
}
|
||||
}
|
||||
// Check for displacement overflow.
|
||||
|
@ -51,3 +51,22 @@ entry:
|
||||
; X64: ret
|
||||
|
||||
}
|
||||
|
||||
define double @test4(i64 %x, double* %p) nounwind {
|
||||
entry:
|
||||
%x.addr = alloca i64, align 8 ; <i64*> [#uses=2]
|
||||
%p.addr = alloca double*, align 8 ; <double**> [#uses=2]
|
||||
store i64 %x, i64* %x.addr
|
||||
store double* %p, double** %p.addr
|
||||
%tmp = load i64* %x.addr ; <i64> [#uses=1]
|
||||
%add = add nsw i64 %tmp, 16 ; <i64> [#uses=1]
|
||||
%tmp1 = load double** %p.addr ; <double*> [#uses=1]
|
||||
%arrayidx = getelementptr inbounds double* %tmp1, i64 %add ; <double*> [#uses=1]
|
||||
%tmp2 = load double* %arrayidx ; <double> [#uses=1]
|
||||
ret double %tmp2
|
||||
|
||||
; X32: test4:
|
||||
; X32: 128(%e{{.*}},%e{{.*}},8)
|
||||
; X64: test4:
|
||||
; X64: 128(%r{{.*}},%r{{.*}},8)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user