From cda8875433ef74c39c4151d1a58df0588168b2e2 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 26 Jun 2008 00:16:49 +0000 Subject: [PATCH] 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@52747 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 29 +++++++++++++++++++++--- test/CodeGen/X86/uint_to_fp.ll | 13 +++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 test/CodeGen/X86/uint_to_fp.ll diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index c07ad27baa6..d39d43e5778 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(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(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 00000000000..3ea7a947b96 --- /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 ; :0 [#uses=1] + uitofp i32 %0 to float ; :1 [#uses=1] + store float %1, float* %y + ret void +}