aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/SelectionDAG/DAGCombiner.cpp29
-rw-r--r--test/CodeGen/X86/uint_to_fp.ll13
2 files changed, 39 insertions, 3 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index c07ad27baa..d39d43e577 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/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();
}
diff --git a/test/CodeGen/X86/uint_to_fp.ll b/test/CodeGen/X86/uint_to_fp.ll
new file mode 100644
index 0000000000..3ea7a947b9
--- /dev/null
+++ b/test/CodeGen/X86/uint_to_fp.ll
@@ -0,0 +1,13 @@
+; RUN: llvm-as < %s | llc -march=x86 -mcpu=yonah | not grep {sub.*esp}
+; rdar://6034396
+
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
+target triple = "i386-apple-darwin8"
+
+define void @test(i32 %x, float* %y) nounwind {
+entry:
+ lshr i32 %x, 23 ; <i32>:0 [#uses=1]
+ uitofp i32 %0 to float ; <float>:1 [#uses=1]
+ store float %1, float* %y
+ ret void
+}