mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-07 11:33:44 +00:00
Factor out the code for sign-extending/truncating gep indices
and use it in x86 address mode folding. Also, make getRegForValue return 0 for illegal types even if it has a ValueMap for them, because Argument values are put in the ValueMap. This fixes PR3181. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@60696 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
11dcd8d38d
commit
c8a1a3c426
@ -106,6 +106,11 @@ public:
|
|||||||
/// defined locally.
|
/// defined locally.
|
||||||
unsigned lookUpRegForValue(Value *V);
|
unsigned lookUpRegForValue(Value *V);
|
||||||
|
|
||||||
|
/// getRegForGEPIndex - This is a wrapper around getRegForValue that also
|
||||||
|
/// takes care of truncating or sign-extending the given getelementptr
|
||||||
|
/// index value.
|
||||||
|
unsigned getRegForGEPIndex(Value *V);
|
||||||
|
|
||||||
virtual ~FastISel();
|
virtual ~FastISel();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -55,6 +55,19 @@
|
|||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
unsigned FastISel::getRegForValue(Value *V) {
|
unsigned FastISel::getRegForValue(Value *V) {
|
||||||
|
MVT::SimpleValueType VT = TLI.getValueType(V->getType()).getSimpleVT();
|
||||||
|
|
||||||
|
// Ignore illegal types. We must do this before looking up the value
|
||||||
|
// in ValueMap because Arguments are given virtual registers regardless
|
||||||
|
// of whether FastISel can handle them.
|
||||||
|
if (!TLI.isTypeLegal(VT)) {
|
||||||
|
// Promote MVT::i1 to a legal type though, because it's common and easy.
|
||||||
|
if (VT == MVT::i1)
|
||||||
|
VT = TLI.getTypeToTransformTo(VT).getSimpleVT();
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Look up the value to see if we already have a register for it. We
|
// Look up the value to see if we already have a register for it. We
|
||||||
// cache values defined by Instructions across blocks, and other values
|
// cache values defined by Instructions across blocks, and other values
|
||||||
// only locally. This is because Instructions already have the SSA
|
// only locally. This is because Instructions already have the SSA
|
||||||
@ -65,17 +78,6 @@ unsigned FastISel::getRegForValue(Value *V) {
|
|||||||
if (Reg != 0)
|
if (Reg != 0)
|
||||||
return Reg;
|
return Reg;
|
||||||
|
|
||||||
MVT::SimpleValueType VT = TLI.getValueType(V->getType()).getSimpleVT();
|
|
||||||
|
|
||||||
// Ignore illegal types.
|
|
||||||
if (!TLI.isTypeLegal(VT)) {
|
|
||||||
// Promote MVT::i1 to a legal type though, because it's common and easy.
|
|
||||||
if (VT == MVT::i1)
|
|
||||||
VT = TLI.getTypeToTransformTo(VT).getSimpleVT();
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
|
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
|
||||||
if (CI->getValue().getActiveBits() <= 64)
|
if (CI->getValue().getActiveBits() <= 64)
|
||||||
Reg = FastEmit_i(VT, VT, ISD::Constant, CI->getZExtValue());
|
Reg = FastEmit_i(VT, VT, ISD::Constant, CI->getZExtValue());
|
||||||
@ -153,6 +155,24 @@ void FastISel::UpdateValueMap(Value* I, unsigned Reg) {
|
|||||||
Reg, MRI.getRegClass(Reg), MRI.getRegClass(Reg));
|
Reg, MRI.getRegClass(Reg), MRI.getRegClass(Reg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned FastISel::getRegForGEPIndex(Value *Idx) {
|
||||||
|
unsigned IdxN = getRegForValue(Idx);
|
||||||
|
if (IdxN == 0)
|
||||||
|
// Unhandled operand. Halt "fast" selection and bail.
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// If the index is smaller or larger than intptr_t, truncate or extend it.
|
||||||
|
MVT PtrVT = TLI.getPointerTy();
|
||||||
|
MVT IdxVT = MVT::getMVT(Idx->getType(), /*HandleUnknown=*/false);
|
||||||
|
if (IdxVT.bitsLT(PtrVT))
|
||||||
|
IdxN = FastEmit_r(IdxVT.getSimpleVT(), PtrVT.getSimpleVT(),
|
||||||
|
ISD::SIGN_EXTEND, IdxN);
|
||||||
|
else if (IdxVT.bitsGT(PtrVT))
|
||||||
|
IdxN = FastEmit_r(IdxVT.getSimpleVT(), PtrVT.getSimpleVT(),
|
||||||
|
ISD::TRUNCATE, IdxN);
|
||||||
|
return IdxN;
|
||||||
|
}
|
||||||
|
|
||||||
/// SelectBinaryOp - Select and emit code for a binary operator instruction,
|
/// SelectBinaryOp - Select and emit code for a binary operator instruction,
|
||||||
/// which has an opcode which directly corresponds to the given ISD opcode.
|
/// which has an opcode which directly corresponds to the given ISD opcode.
|
||||||
///
|
///
|
||||||
@ -263,18 +283,7 @@ bool FastISel::SelectGetElementPtr(User *I) {
|
|||||||
|
|
||||||
// N = N + Idx * ElementSize;
|
// N = N + Idx * ElementSize;
|
||||||
uint64_t ElementSize = TD.getABITypeSize(Ty);
|
uint64_t ElementSize = TD.getABITypeSize(Ty);
|
||||||
unsigned IdxN = getRegForValue(Idx);
|
unsigned IdxN = getRegForGEPIndex(Idx);
|
||||||
if (IdxN == 0)
|
|
||||||
// Unhandled operand. Halt "fast" selection and bail.
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// If the index is smaller or larger than intptr_t, truncate or extend
|
|
||||||
// it.
|
|
||||||
MVT IdxVT = MVT::getMVT(Idx->getType(), /*HandleUnknown=*/false);
|
|
||||||
if (IdxVT.bitsLT(VT))
|
|
||||||
IdxN = FastEmit_r(IdxVT.getSimpleVT(), VT, ISD::SIGN_EXTEND, IdxN);
|
|
||||||
else if (IdxVT.bitsGT(VT))
|
|
||||||
IdxN = FastEmit_r(IdxVT.getSimpleVT(), VT, ISD::TRUNCATE, IdxN);
|
|
||||||
if (IdxN == 0)
|
if (IdxN == 0)
|
||||||
// Unhandled operand. Halt "fast" selection and bail.
|
// Unhandled operand. Halt "fast" selection and bail.
|
||||||
return false;
|
return false;
|
||||||
|
@ -372,8 +372,8 @@ bool X86FastISel::X86SelectAddress(Value *V, X86AddressMode &AM, bool isCall) {
|
|||||||
unsigned IndexReg = AM.IndexReg;
|
unsigned IndexReg = AM.IndexReg;
|
||||||
unsigned Scale = AM.Scale;
|
unsigned Scale = AM.Scale;
|
||||||
gep_type_iterator GTI = gep_type_begin(U);
|
gep_type_iterator GTI = gep_type_begin(U);
|
||||||
// Look at all but the last index. Constants can be folded,
|
// Iterate through the indices, folding what we can. Constants can be
|
||||||
// and one dynamic index can be handled, if the scale is supported.
|
// folded, and one dynamic index can be handled, if the scale is supported.
|
||||||
for (User::op_iterator i = U->op_begin() + 1, e = U->op_end();
|
for (User::op_iterator i = U->op_begin() + 1, e = U->op_end();
|
||||||
i != e; ++i, ++GTI) {
|
i != e; ++i, ++GTI) {
|
||||||
Value *Op = *i;
|
Value *Op = *i;
|
||||||
@ -392,7 +392,7 @@ bool X86FastISel::X86SelectAddress(Value *V, X86AddressMode &AM, bool isCall) {
|
|||||||
(S == 1 || S == 2 || S == 4 || S == 8)) {
|
(S == 1 || S == 2 || S == 4 || S == 8)) {
|
||||||
// Scaled-index addressing.
|
// Scaled-index addressing.
|
||||||
Scale = S;
|
Scale = S;
|
||||||
IndexReg = getRegForValue(Op);
|
IndexReg = getRegForGEPIndex(Op);
|
||||||
if (IndexReg == 0)
|
if (IndexReg == 0)
|
||||||
return false;
|
return false;
|
||||||
} else
|
} else
|
||||||
|
17
test/CodeGen/X86/fast-isel-gep-sext.ll
Normal file
17
test/CodeGen/X86/fast-isel-gep-sext.ll
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
; RUN: llvm-as < %s | llc -march=x86-64 -fast | grep movslq
|
||||||
|
; RUN: llvm-as < %s | llc -march=x86 -fast
|
||||||
|
; PR3181
|
||||||
|
|
||||||
|
; GEP indices are interpreted as signed integers, so they
|
||||||
|
; should be sign-extended to 64 bits on 64-bit targets.
|
||||||
|
|
||||||
|
define i32 @foo(i32 %t3, i32* %t1) nounwind {
|
||||||
|
%t9 = getelementptr i32* %t1, i32 %t3 ; <i32*> [#uses=1]
|
||||||
|
%t15 = load i32* %t9 ; <i32> [#uses=1]
|
||||||
|
ret i32 %t15
|
||||||
|
}
|
||||||
|
define i32 @bar(i64 %t3, i32* %t1) nounwind {
|
||||||
|
%t9 = getelementptr i32* %t1, i64 %t3 ; <i32*> [#uses=1]
|
||||||
|
%t15 = load i32* %t9 ; <i32> [#uses=1]
|
||||||
|
ret i32 %t15
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user