diff options
author | Owen Anderson <resistor@mac.com> | 2012-07-09 20:31:12 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2012-07-09 20:31:12 +0000 |
commit | d9bf71fdd26475f4629ef8861debfd2c621a372f (patch) | |
tree | 6e797d4b8428dc76be7375412b7a1e74a103492f | |
parent | 6209364834a4c0ca720d3fcc9ef7fa4c1fb39ecc (diff) | |
download | llvm-d9bf71fdd26475f4629ef8861debfd2c621a372f.tar.gz llvm-d9bf71fdd26475f4629ef8861debfd2c621a372f.tar.bz2 llvm-d9bf71fdd26475f4629ef8861debfd2c621a372f.tar.xz |
Teach the DAG combiner to turn sitofp/uitofp from i1 into a conditional move, since there are only two possible values.
Previously, this would become an integer extension operation, followed by a real integer->float conversion.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@159957 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 36 | ||||
-rw-r--r-- | test/CodeGen/ARM/select.ll | 26 |
2 files changed, 62 insertions, 0 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 28c3be9eb6..02877862b4 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -5974,6 +5974,30 @@ SDValue DAGCombiner::visitSINT_TO_FP(SDNode *N) { return DAG.getNode(ISD::UINT_TO_FP, N->getDebugLoc(), VT, N0); } + // fold (sint_to_fp (setcc x, y, cc)) -> (select_cc x, y, -1.0, 0.0,, cc) + if (N0.getOpcode() == ISD::SETCC && !VT.isVector() && + (!LegalOperations || + TLI.isOperationLegalOrCustom(llvm::ISD::ConstantFP, VT))) { + SDValue Ops[] = + { N0.getOperand(0), N0.getOperand(1), + DAG.getConstantFP(-1.0, VT) , DAG.getConstantFP(0.0, VT), + N0.getOperand(2) }; + return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), VT, Ops, 5); + } + + // fold (sint_to_fp (zext (setcc x, y, cc))) -> + // (select_cc x, y, 1.0, 0.0,, cc) + if (N0.getOpcode() == ISD::ZERO_EXTEND && + N0.getOperand(0).getOpcode() == ISD::SETCC &&!VT.isVector() && + (!LegalOperations || + TLI.isOperationLegalOrCustom(llvm::ISD::ConstantFP, VT))) { + SDValue Ops[] = + { N0.getOperand(0).getOperand(0), N0.getOperand(0).getOperand(1), + DAG.getConstantFP(1.0, VT) , DAG.getConstantFP(0.0, VT), + N0.getOperand(0).getOperand(2) }; + return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), VT, Ops, 5); + } + return SDValue(); } @@ -5999,6 +6023,18 @@ SDValue DAGCombiner::visitUINT_TO_FP(SDNode *N) { return DAG.getNode(ISD::SINT_TO_FP, N->getDebugLoc(), VT, N0); } + // fold (uint_to_fp (setcc x, y, cc)) -> (select_cc x, y, -1.0, 0.0,, cc) + if (N0.getOpcode() == ISD::SETCC && !VT.isVector() && + (!LegalOperations || + TLI.isOperationLegalOrCustom(llvm::ISD::ConstantFP, VT))) { + SDValue Ops[] = + { N0.getOperand(0), N0.getOperand(1), + DAG.getConstantFP(1.0, VT), DAG.getConstantFP(0.0, VT), + N0.getOperand(2) }; + return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), VT, Ops, 5); + } + + return SDValue(); } diff --git a/test/CodeGen/ARM/select.ll b/test/CodeGen/ARM/select.ll index 3e07da841a..418d4f31ee 100644 --- a/test/CodeGen/ARM/select.ll +++ b/test/CodeGen/ARM/select.ll @@ -113,3 +113,29 @@ entry: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, [2 x i32], i32, float)*)(i8* undef, i8* undef, [2 x i32] %tmp493, i32 0, float 1.000000e+00) optsize ret void } + +; CHECK: f10 +define float @f10(i32 %a, i32 %b) nounwind uwtable readnone ssp { +; CHECK-NOT: floatsisf + %1 = icmp eq i32 %a, %b + %2 = zext i1 %1 to i32 + %3 = sitofp i32 %2 to float + ret float %3 +} + +; CHECK: f11 +define float @f11(i32 %a, i32 %b) nounwind uwtable readnone ssp { +; CHECK-NOT: floatsisf + %1 = icmp eq i32 %a, %b + %2 = sitofp i1 %1 to float + ret float %2 +} + +; CHECK: f12 +define float @f12(i32 %a, i32 %b) nounwind uwtable readnone ssp { +; CHECK-NOT: floatunsisf + %1 = icmp eq i32 %a, %b + %2 = uitofp i1 %1 to float + ret float %2 +} + |