[llvm-commits] [llvm] r60696 - in /llvm/trunk: include/llvm/CodeGen/FastISel.h lib/CodeGen/SelectionDAG/FastISel.cpp lib/Target/X86/X86FastISel.cpp test/CodeGen/X86/fast-isel-gep-sext.ll
Dan Gohman
gohman at apple.com
Sun Dec 7 23:57:47 PST 2008
Author: djg
Date: Mon Dec 8 01:57:47 2008
New Revision: 60696
URL: http://llvm.org/viewvc/llvm-project?rev=60696&view=rev
Log:
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.
Added:
llvm/trunk/test/CodeGen/X86/fast-isel-gep-sext.ll
Modified:
llvm/trunk/include/llvm/CodeGen/FastISel.h
llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp
llvm/trunk/lib/Target/X86/X86FastISel.cpp
Modified: llvm/trunk/include/llvm/CodeGen/FastISel.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/FastISel.h?rev=60696&r1=60695&r2=60696&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/FastISel.h (original)
+++ llvm/trunk/include/llvm/CodeGen/FastISel.h Mon Dec 8 01:57:47 2008
@@ -106,6 +106,11 @@
/// defined locally.
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();
protected:
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=60696&r1=60695&r2=60696&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Mon Dec 8 01:57:47 2008
@@ -55,19 +55,11 @@
using namespace llvm;
unsigned FastISel::getRegForValue(Value *V) {
- // 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
- // only locally. This is because Instructions already have the SSA
- // def-dominatess-use requirement enforced.
- if (ValueMap.count(V))
- return ValueMap[V];
- unsigned Reg = LocalValueMap[V];
- if (Reg != 0)
- return Reg;
-
MVT::SimpleValueType VT = TLI.getValueType(V->getType()).getSimpleVT();
- // Ignore illegal types.
+ // 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)
@@ -76,6 +68,16 @@
return 0;
}
+ // 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
+ // only locally. This is because Instructions already have the SSA
+ // def-dominatess-use requirement enforced.
+ if (ValueMap.count(V))
+ return ValueMap[V];
+ unsigned Reg = LocalValueMap[V];
+ if (Reg != 0)
+ return Reg;
+
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
if (CI->getValue().getActiveBits() <= 64)
Reg = FastEmit_i(VT, VT, ISD::Constant, CI->getZExtValue());
@@ -153,6 +155,24 @@
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,
/// which has an opcode which directly corresponds to the given ISD opcode.
///
@@ -263,18 +283,7 @@
// N = N + Idx * ElementSize;
uint64_t ElementSize = TD.getABITypeSize(Ty);
- unsigned IdxN = getRegForValue(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);
+ unsigned IdxN = getRegForGEPIndex(Idx);
if (IdxN == 0)
// Unhandled operand. Halt "fast" selection and bail.
return false;
Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=60696&r1=60695&r2=60696&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86FastISel.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86FastISel.cpp Mon Dec 8 01:57:47 2008
@@ -372,8 +372,8 @@
unsigned IndexReg = AM.IndexReg;
unsigned Scale = AM.Scale;
gep_type_iterator GTI = gep_type_begin(U);
- // Look at all but the last index. Constants can be folded,
- // and one dynamic index can be handled, if the scale is supported.
+ // Iterate through the indices, folding what we can. Constants can be
+ // 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();
i != e; ++i, ++GTI) {
Value *Op = *i;
@@ -392,7 +392,7 @@
(S == 1 || S == 2 || S == 4 || S == 8)) {
// Scaled-index addressing.
Scale = S;
- IndexReg = getRegForValue(Op);
+ IndexReg = getRegForGEPIndex(Op);
if (IndexReg == 0)
return false;
} else
Added: llvm/trunk/test/CodeGen/X86/fast-isel-gep-sext.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fast-isel-gep-sext.ll?rev=60696&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/fast-isel-gep-sext.ll (added)
+++ llvm/trunk/test/CodeGen/X86/fast-isel-gep-sext.ll Mon Dec 8 01:57:47 2008
@@ -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
+}
More information about the llvm-commits
mailing list