1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 19:12:56 +02:00

Teach X86FastISel to fold constant offsets and scaled indices in

the same address.

llvm-svn: 107373
This commit is contained in:
Dan Gohman 2010-07-01 02:27:15 +00:00
parent bac963d556
commit 243bda093e
2 changed files with 42 additions and 14 deletions

View File

@ -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.

View File

@ -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)
}