diff options
author | Chris Lattner <sabre@nondot.org> | 2008-06-26 00:16:49 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-06-26 00:16:49 +0000 |
commit | b1e66ce3bb6c7a629cb7dd4c84e32ab37536b41d (patch) | |
tree | 4b556e1fea595cc7de34ceaf3c9167898e0d3911 /llvm/lib/CodeGen | |
parent | f7b72b69405fb064ce5329ebdcaac5245ca08ed8 (diff) | |
download | bcm5719-llvm-b1e66ce3bb6c7a629cb7dd4c84e32ab37536b41d.tar.gz bcm5719-llvm-b1e66ce3bb6c7a629cb7dd4c84e32ab37536b41d.zip |
when we know the signbit of an input to uint_to_fp is zero,
change it to sint_to_fp on targets where that is cheaper (and
visaversa of course). This allows us to compile uint_to_fp to:
_test:
movl 4(%esp), %eax
shrl $23, %eax
cvtsi2ss %eax, %xmm0
movl 8(%esp), %eax
movss %xmm0, (%eax)
ret
instead of:
.align 3
LCPI1_0: ## double
.long 0 ## double least significant word 4.5036e+15
.long 1127219200 ## double most significant word 4.5036e+15
.text
.align 4,0x90
.globl _test
_test:
subl $12, %esp
movl 16(%esp), %eax
shrl $23, %eax
movl %eax, (%esp)
movl $1127219200, 4(%esp)
movsd (%esp), %xmm0
subsd LCPI1_0, %xmm0
cvtsd2ss %xmm0, %xmm0
movl 20(%esp), %eax
movss %xmm0, (%eax)
addl $12, %esp
ret
llvm-svn: 52747
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index c07ad27baa6..d39d43e5778 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3844,10 +3844,22 @@ SDOperand DAGCombiner::visitSINT_TO_FP(SDNode *N) { SDOperand N0 = N->getOperand(0); ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0); MVT VT = N->getValueType(0); - + MVT OpVT = N0.getValueType(); + // fold (sint_to_fp c1) -> c1fp - if (N0C && N0.getValueType() != MVT::ppcf128) + if (N0C && OpVT != MVT::ppcf128) return DAG.getNode(ISD::SINT_TO_FP, VT, N0); + + // If the input is a legal type, and SINT_TO_FP is not legal on this target, + // but UINT_TO_FP is legal on this target, try to convert. + if (TLI.isTypeLegal(OpVT) && !TLI.isOperationLegal(ISD::SINT_TO_FP, OpVT) && + TLI.isOperationLegal(ISD::UINT_TO_FP, OpVT)) { + // If the sign bit is known to be zero, we can change this to UINT_TO_FP. + if (DAG.SignBitIsZero(N0)) + return DAG.getNode(ISD::UINT_TO_FP, VT, N0); + } + + return SDOperand(); } @@ -3855,10 +3867,21 @@ SDOperand DAGCombiner::visitUINT_TO_FP(SDNode *N) { SDOperand N0 = N->getOperand(0); ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0); MVT VT = N->getValueType(0); + MVT OpVT = N0.getValueType(); // fold (uint_to_fp c1) -> c1fp - if (N0C && N0.getValueType() != MVT::ppcf128) + if (N0C && OpVT != MVT::ppcf128) return DAG.getNode(ISD::UINT_TO_FP, VT, N0); + + // If the input is a legal type, and UINT_TO_FP is not legal on this target, + // but SINT_TO_FP is legal on this target, try to convert. + if (TLI.isTypeLegal(OpVT) && !TLI.isOperationLegal(ISD::UINT_TO_FP, OpVT) && + TLI.isOperationLegal(ISD::SINT_TO_FP, OpVT)) { + // If the sign bit is known to be zero, we can change this to SINT_TO_FP. + if (DAG.SignBitIsZero(N0)) + return DAG.getNode(ISD::SINT_TO_FP, VT, N0); + } + return SDOperand(); } |