[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp
Chris Lattner
lattner at cs.uiuc.edu
Fri Jul 15 17:28:31 PDT 2005
Changes in directory llvm/lib/Target/X86:
X86ISelPattern.cpp updated: 1.151 -> 1.152
---
Log message:
Remove all knowledge of UINT_TO_FP from the X86 backend, relying on the
legalizer to eliminate them. With this comes the expected code quality
improvements, such as, for this:
double foo(unsigned short X) { return X; }
we now generate this:
_foo:
subl $4, %esp
movzwl 8(%esp), %eax
movl %eax, (%esp)
fildl (%esp)
addl $4, %esp
ret
instead of this:
_foo:
subl $4, %esp
movw 8(%esp), %ax
movzwl %ax, %eax ;; Load not folded into this.
movl %eax, (%esp)
fildl (%esp)
addl $4, %esp
ret
-Chris
---
Diffs of the changes: (+27 -53)
X86ISelPattern.cpp | 80 +++++++++++++++++------------------------------------
1 files changed, 27 insertions(+), 53 deletions(-)
Index: llvm/lib/Target/X86/X86ISelPattern.cpp
diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.151 llvm/lib/Target/X86/X86ISelPattern.cpp:1.152
--- llvm/lib/Target/X86/X86ISelPattern.cpp:1.151 Thu Jul 14 19:38:55 2005
+++ llvm/lib/Target/X86/X86ISelPattern.cpp Fri Jul 15 19:28:20 2005
@@ -106,7 +106,16 @@
addRegisterClass(MVT::i16, X86::R16RegisterClass);
addRegisterClass(MVT::i32, X86::R32RegisterClass);
+ // Promote all UINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have this
+ // operation.
+ setOperationAction(ISD::UINT_TO_FP , MVT::i1 , Promote);
+ setOperationAction(ISD::UINT_TO_FP , MVT::i8 , Promote);
+ setOperationAction(ISD::UINT_TO_FP , MVT::i16 , Promote);
+ setOperationAction(ISD::UINT_TO_FP , MVT::i32 , Promote);
+
+ // We can handle SINT_TO_FP from i64 even though i64 isn't legal.
setOperationAction(ISD::SINT_TO_FP , MVT::i64 , Custom);
+
setOperationAction(ISD::BRCONDTWOWAY , MVT::Other, Expand);
setOperationAction(ISD::MEMMOVE , MVT::Other, Expand);
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16 , Expand);
@@ -912,6 +921,10 @@
return std::make_pair(Result, Chain);
}
+//===----------------------------------------------------------------------===//
+// X86 Custom Lowering Hooks
+//===----------------------------------------------------------------------===//
+
/// LowerOperation - Provide custom lowering hooks for some operations.
///
SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
@@ -2346,8 +2359,7 @@
BuildMI(BB, Opc, 1, Result).addReg(Tmp2);
return Result;
- case ISD::SINT_TO_FP:
- case ISD::UINT_TO_FP: {
+ case ISD::SINT_TO_FP: {
Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
unsigned PromoteOpcode = 0;
@@ -2357,17 +2369,14 @@
MVT::ValueType SrcTy = N.getOperand(0).getValueType();
MVT::ValueType DstTy = N.getValueType();
switch (SrcTy) {
- case MVT::i1:
- case MVT::i8:
- PromoteOpcode = (N.getOpcode() == ISD::UINT_TO_FP) ?
- X86::MOVZX32rr8 : X86::MOVSX32rr8;
+ case MVT::i1: // FIXME: Should teach legalize about SINT_TO_FP i1/i8/i16
+ case MVT::i8: // promotion, just like UINT_TO_FP promotion.
+ PromoteOpcode = X86::MOVSX32rr8;
break;
case MVT::i16:
- PromoteOpcode = (N.getOpcode() == ISD::UINT_TO_FP) ?
- X86::MOVZX32rr16 : X86::MOVSX32rr16;
+ PromoteOpcode = X86::MOVSX32rr16;
break;
default:
- assert(N.getOpcode() != ISD::UINT_TO_FP);
break;
}
if (PromoteOpcode) {
@@ -2386,38 +2395,23 @@
// are no unsigned FLD instructions, so we must promote an unsigned value to
// a larger signed value, then use FLD on the larger value.
//
- MVT::ValueType PromoteType = MVT::Other;
MVT::ValueType SrcTy = N.getOperand(0).getValueType();
- unsigned RealDestReg = Result;
switch (SrcTy) {
case MVT::i1:
case MVT::i8:
// We don't have the facilities for directly loading byte sized data from
// memory (even signed). Promote it to 16 bits.
- PromoteType = MVT::i16;
- PromoteOpcode = Node->getOpcode() == ISD::SINT_TO_FP ?
- X86::MOVSX16rr8 : X86::MOVZX16rr8;
- break;
- case MVT::i16:
- if (Node->getOpcode() == ISD::UINT_TO_FP) {
- PromoteType = MVT::i32;
- PromoteOpcode = X86::MOVZX32rr16;
- }
+
+ // FIXME: move to legalize.
+ Tmp2 = MakeReg(MVT::i16);
+ BuildMI(BB, X86::MOVSX16rr8, 1, Tmp2).addReg(Tmp1);
+ SrcTy = MVT::i16;
+ Tmp1 = Tmp2;
break;
default:
- // Don't fild into the real destination.
- if (Node->getOpcode() == ISD::UINT_TO_FP)
- Result = MakeReg(Node->getValueType(0));
break;
}
- if (PromoteType != MVT::Other) {
- Tmp2 = MakeReg(PromoteType);
- BuildMI(BB, PromoteOpcode, 1, Tmp2).addReg(Tmp1);
- SrcTy = PromoteType;
- Tmp1 = Tmp2;
- }
-
// Spill the integer to memory and reload it from there.
unsigned Size = MVT::getSizeInBits(SrcTy)/8;
MachineFunction *F = BB->getParent();
@@ -2425,36 +2419,16 @@
switch (SrcTy) {
case MVT::i32:
- addFrameReference(BuildMI(BB, X86::MOV32mr, 5),
- FrameIdx).addReg(Tmp1);
+ addFrameReference(BuildMI(BB, X86::MOV32mr, 5), FrameIdx).addReg(Tmp1);
addFrameReference(BuildMI(BB, X86::FILD32m, 5, Result), FrameIdx);
break;
case MVT::i16:
- addFrameReference(BuildMI(BB, X86::MOV16mr, 5),
- FrameIdx).addReg(Tmp1);
+ addFrameReference(BuildMI(BB, X86::MOV16mr, 5), FrameIdx).addReg(Tmp1);
addFrameReference(BuildMI(BB, X86::FILD16m, 5, Result), FrameIdx);
break;
default: break; // No promotion required.
}
-
- if (Node->getOpcode() == ISD::UINT_TO_FP && Result != RealDestReg) {
- // If this is a cast from uint -> double, we need to be careful when if
- // the "sign" bit is set. If so, we don't want to make a negative number,
- // we want to make a positive number. Emit code to add an offset if the
- // sign bit is set.
-
- // Compute whether the sign bit is set by shifting the reg right 31 bits.
- unsigned IsNeg = MakeReg(MVT::i32);
- BuildMI(BB, X86::SHR32ri, 2, IsNeg).addReg(Tmp1).addImm(31);
-
- // Create a CP value that has the offset in one word and 0 in the other.
- static ConstantInt *TheOffset = ConstantUInt::get(Type::ULongTy,
- 0x4f80000000000000ULL);
- unsigned CPI = F->getConstantPool()->getConstantPoolIndex(TheOffset);
- BuildMI(BB, X86::FADD32m, 5, RealDestReg).addReg(Result)
- .addConstantPoolIndex(CPI).addZImm(4).addReg(IsNeg).addSImm(0);
- }
- return RealDestReg;
+ return Result;
}
case ISD::FP_TO_SINT:
case ISD::FP_TO_UINT: {
More information about the llvm-commits
mailing list