diff options
author | Nate Begeman <natebegeman@mac.com> | 2005-07-16 02:02:34 +0000 |
---|---|---|
committer | Nate Begeman <natebegeman@mac.com> | 2005-07-16 02:02:34 +0000 |
commit | 5a8441ea3fc145393d6274156bd05c4a006099ea (patch) | |
tree | cc5a8d6efc77c3e61d52510456c108fd2b4c9f27 /lib/CodeGen | |
parent | 11cefd926a1be9e6cd52b4e189a99081a385d57f (diff) |
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
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index ee515fd390..701e528289 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: |