aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNate Begeman <natebegeman@mac.com>2005-07-16 02:02:34 +0000
committerNate Begeman <natebegeman@mac.com>2005-07-16 02:02:34 +0000
commit5a8441ea3fc145393d6274156bd05c4a006099ea (patch)
treecc5a8d6efc77c3e61d52510456c108fd2b4c9f27
parent11cefd926a1be9e6cd52b4e189a99081a385d57f (diff)
downloadexternal_llvm-5a8441ea3fc145393d6274156bd05c4a006099ea.zip
external_llvm-5a8441ea3fc145393d6274156bd05c4a006099ea.tar.gz
external_llvm-5a8441ea3fc145393d6274156bd05c4a006099ea.tar.bz2
Teach the legalizer how to promote SINT_TO_FP to a wider SINT_TO_FP that
the target natively supports. This eliminates some special-case code from the x86 backend and generates better code as well. For an i8 to f64 conversion, before & after: _x87 before: subl $2, %esp movb 6(%esp), %al movsbw %al, %ax movw %ax, (%esp) filds (%esp) addl $2, %esp ret _x87 after: subl $2, %esp movsbw 6(%esp), %ax movw %ax, (%esp) filds (%esp) addl $2, %esp ret _sse before: subl $12, %esp movb 16(%esp), %al movsbl %al, %eax cvtsi2sd %eax, %xmm0 addl $12, %esp ret _sse after: subl $12, %esp movsbl 16(%esp), %eax cvtsi2sd %eax, %xmm0 addl $12, %esp ret git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22452 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp28
-rw-r--r--lib/Target/X86/X86ISelPattern.cpp65
2 files changed, 39 insertions, 54 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index ee515fd3..701e528 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -126,7 +126,8 @@ private:
SDOperand Source);
SDOperand ExpandLegalUINT_TO_FP(SDOperand LegalOp, MVT::ValueType DestVT);
- SDOperand PromoteLegalUINT_TO_FP(SDOperand LegalOp, MVT::ValueType DestVT);
+ SDOperand PromoteLegalINT_TO_FP(SDOperand LegalOp, MVT::ValueType DestVT,
+ bool isSigned);
bool ExpandShift(unsigned Opc, SDOperand Op, SDOperand Amt,
SDOperand &Lo, SDOperand &Hi);
@@ -197,8 +198,9 @@ SDOperand SelectionDAGLegalize::ExpandLegalUINT_TO_FP(SDOperand Op0,
/// we promote it. At this point, we know that the result and operand types are
/// legal for the target, and that there is a legal UINT_TO_FP or SINT_TO_FP
/// operation that takes a larger input.
-SDOperand SelectionDAGLegalize::PromoteLegalUINT_TO_FP(SDOperand LegalOp,
- MVT::ValueType DestVT) {
+SDOperand SelectionDAGLegalize::PromoteLegalINT_TO_FP(SDOperand LegalOp,
+ MVT::ValueType DestVT,
+ bool isSigned) {
// First step, figure out the appropriate *INT_TO_FP operation to use.
MVT::ValueType NewInTy = LegalOp.getValueType();
@@ -221,6 +223,7 @@ SDOperand SelectionDAGLegalize::PromoteLegalUINT_TO_FP(SDOperand LegalOp,
break;
}
if (OpToUse) break;
+ if (isSigned) continue;
// If the target supports UINT_TO_FP of this type, use it.
switch (TLI.getOperationAction(ISD::UINT_TO_FP, NewInTy)) {
@@ -244,7 +247,8 @@ SDOperand SelectionDAGLegalize::PromoteLegalUINT_TO_FP(SDOperand LegalOp,
// Okay, we found the operation and type to use. Zero extend our input to the
// desired type then run the operation on it.
return DAG.getNode(OpToUse, DestVT,
- DAG.getNode(ISD::ZERO_EXTEND, NewInTy, LegalOp));
+ DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND,
+ NewInTy, LegalOp));
}
void SelectionDAGLegalize::LegalizeDAG() {
@@ -1438,18 +1442,24 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
switch (getTypeAction(Node->getOperand(0).getValueType())) {
case Legal:
//still made need to expand if the op is illegal, but the types are legal
- if (Node->getOpcode() == ISD::UINT_TO_FP) {
+ if (Node->getOpcode() == ISD::UINT_TO_FP ||
+ Node->getOpcode() == ISD::SINT_TO_FP) {
+ bool isSigned = Node->getOpcode() == ISD::SINT_TO_FP;
switch (TLI.getOperationAction(Node->getOpcode(),
Node->getOperand(0).getValueType())) {
default: assert(0 && "Unknown operation action!");
case TargetLowering::Expand:
- Result = ExpandLegalUINT_TO_FP(LegalizeOp(Node->getOperand(0)),
- Node->getValueType(0));
+ if (!isSigned)
+ Result = ExpandLegalUINT_TO_FP(LegalizeOp(Node->getOperand(0)),
+ Node->getValueType(0));
+ else
+ assert(0 && "Legalize cannot Expand SINT_TO_FP yet");
AddLegalizedOperand(Op, Result);
return Result;
case TargetLowering::Promote:
- Result = PromoteLegalUINT_TO_FP(LegalizeOp(Node->getOperand(0)),
- Node->getValueType(0));
+ Result = PromoteLegalINT_TO_FP(LegalizeOp(Node->getOperand(0)),
+ Node->getValueType(0),
+ isSigned);
AddLegalizedOperand(Op, Result);
return Result;
case TargetLowering::Legal:
diff --git a/lib/Target/X86/X86ISelPattern.cpp b/lib/Target/X86/X86ISelPattern.cpp
index 6378663..999f089 100644
--- a/lib/Target/X86/X86ISelPattern.cpp
+++ b/lib/Target/X86/X86ISelPattern.cpp
@@ -112,6 +112,11 @@ namespace {
setOperationAction(ISD::UINT_TO_FP , MVT::i8 , Promote);
setOperationAction(ISD::UINT_TO_FP , MVT::i16 , Promote);
setOperationAction(ISD::UINT_TO_FP , MVT::i32 , Promote);
+
+ // Promote i1/i8 SINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have
+ // this operation.
+ setOperationAction(ISD::SINT_TO_FP , MVT::i1 , Promote);
+ setOperationAction(ISD::SINT_TO_FP , MVT::i8 , Promote);
// We can handle SINT_TO_FP from i64 even though i64 isn't legal.
setOperationAction(ISD::SINT_TO_FP , MVT::i64 , Custom);
@@ -151,9 +156,13 @@ namespace {
addRegisterClass(MVT::f32, X86::RXMMRegisterClass);
addRegisterClass(MVT::f64, X86::RXMMRegisterClass);
+ // SSE has no load+extend ops
setOperationAction(ISD::EXTLOAD, MVT::f32, Expand);
setOperationAction(ISD::ZEXTLOAD, MVT::f32, Expand);
-
+
+ // SSE has no i16 to fp conversion, only i32
+ setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote);
+
// We don't support sin/cos/sqrt/fmod
setOperationAction(ISD::FSIN , MVT::f64, Expand);
setOperationAction(ISD::FCOS , MVT::f64, Expand);
@@ -2363,56 +2372,17 @@ unsigned ISel::SelectExpr(SDOperand N) {
Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
unsigned PromoteOpcode = 0;
- // We can handle any sint to fp, and 8 and 16 uint to fp with the direct
- // sse conversion instructions.
+ // We can handle any sint to fp with the direct sse conversion instructions.
if (X86ScalarSSE) {
- MVT::ValueType SrcTy = N.getOperand(0).getValueType();
- MVT::ValueType DstTy = N.getValueType();
- switch (SrcTy) {
- 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 = X86::MOVSX32rr16;
- break;
- default:
- break;
- }
- if (PromoteOpcode) {
- BuildMI(BB, PromoteOpcode, 1, Tmp2).addReg(Tmp1);
- Tmp1 = Tmp2;
- }
- Opc = (DstTy == MVT::f64) ? X86::CVTSI2SDrr : X86::CVTSI2SSrr;
+ Opc = (N.getValueType() == MVT::f64) ? X86::CVTSI2SDrr : X86::CVTSI2SSrr;
BuildMI(BB, Opc, 1, Result).addReg(Tmp1);
return Result;
}
- // FIXME: Most of this grunt work should be done by legalize!
ContainsFPCode = true;
- // Promote the integer to a type supported by FLD. We do this because there
- // 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 SrcTy = N.getOperand(0).getValueType();
- 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.
-
- // FIXME: move to legalize.
- Tmp2 = MakeReg(MVT::i16);
- BuildMI(BB, X86::MOVSX16rr8, 1, Tmp2).addReg(Tmp1);
- SrcTy = MVT::i16;
- Tmp1 = Tmp2;
- break;
- default:
- break;
- }
-
// Spill the integer to memory and reload it from there.
+ MVT::ValueType SrcTy = N.getOperand(0).getValueType();
unsigned Size = MVT::getSizeInBits(SrcTy)/8;
MachineFunction *F = BB->getParent();
int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, Size);
@@ -3345,8 +3315,13 @@ unsigned ISel::SelectExpr(SDOperand N) {
SelectAddress(Address, AM);
Select(Chain);
}
-
- addFullAddress(BuildMI(BB, X86::FILD64m, 4, Result), AM);
+ if (X86ScalarSSE) {
+ addFullAddress(BuildMI(BB, X86::FILD64m, 4, X86::FP0), AM);
+ addFullAddress(BuildMI(BB, X86::FST64m, 5), AM).addReg(X86::FP0);
+ addFullAddress(BuildMI(BB, X86::MOVSDrm, 4, Result), AM);
+ } else {
+ addFullAddress(BuildMI(BB, X86::FILD64m, 4, Result), AM);
+ }
}
return Result;