llvm.org GIT mirror llvm / 2deb1d0
SelectionDAG: fold (fp_to_u/sint (s/uint_to_fp)) here too Update SPARC tests to match. From: Fiona Glaser <fglaser@apple.com> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@229438 91177308-0d34-0410-b5e6-96231b3b80d8 Mehdi Amini 5 years ago
4 changed file(s) with 99 addition(s) and 19 deletion(s). Raw diff Collapse all Expand all
78447844 return SDValue();
78457845 }
78467846
7847 // Fold (fp_to_{s/u}int ({s/u}int_to_fpx)) -> zext x, sext x, trunc x, or x
7848 static SDValue FoldIntToFPToInt(SDNode *N, SelectionDAG &DAG) {
7849 SDValue N0 = N->getOperand(0);
7850 EVT VT = N->getValueType(0);
7851
7852 if (N0.getOpcode() != ISD::UINT_TO_FP && N0.getOpcode() != ISD::SINT_TO_FP)
7853 return SDValue();
7854
7855 SDValue Src = N0.getOperand(0);
7856 EVT SrcVT = Src.getValueType();
7857 bool IsInputSigned = N0.getOpcode() == ISD::SINT_TO_FP;
7858 bool IsOutputSigned = N->getOpcode() == ISD::FP_TO_SINT;
7859
7860 // We can safely assume the conversion won't overflow the output range,
7861 // because (for example) (uint8_t)18293.f is undefined behavior.
7862
7863 // Since we can assume the conversion won't overflow, our decision as to
7864 // whether the input will fit in the float should depend on the minimum
7865 // of the input range and output range.
7866
7867 // This means this is also safe for a signed input and unsigned output, since
7868 // a negative input would lead to undefined behavior.
7869 unsigned InputSize = (int)SrcVT.getScalarSizeInBits() - IsInputSigned;
7870 unsigned OutputSize = (int)VT.getScalarSizeInBits() - IsOutputSigned;
7871 unsigned ActualSize = std::min(InputSize, OutputSize);
7872 const fltSemantics &sem = DAG.EVTToAPFloatSemantics(N0.getValueType());
7873
7874 // We can only fold away the float conversion if the input range can be
7875 // represented exactly in the float range.
7876 if (APFloat::semanticsPrecision(sem) >= ActualSize) {
7877 if (VT.getScalarSizeInBits() > SrcVT.getScalarSizeInBits()) {
7878 unsigned ExtOp = IsInputSigned && IsOutputSigned ? ISD::SIGN_EXTEND
7879 : ISD::ZERO_EXTEND;
7880 return DAG.getNode(ExtOp, SDLoc(N), VT, Src);
7881 }
7882 if (VT.getScalarSizeInBits() < SrcVT.getScalarSizeInBits())
7883 return DAG.getNode(ISD::TRUNCATE, SDLoc(N), VT, Src);
7884 if (SrcVT == VT)
7885 return Src;
7886 return DAG.getNode(ISD::BITCAST, SDLoc(N), VT, Src);
7887 }
7888 return SDValue();
7889 }
7890
78477891 SDValue DAGCombiner::visitFP_TO_SINT(SDNode *N) {
78487892 SDValue N0 = N->getOperand(0);
78497893 ConstantFPSDNode *N0CFP = dyn_cast(N0);
78537897 if (N0CFP)
78547898 return DAG.getNode(ISD::FP_TO_SINT, SDLoc(N), VT, N0);
78557899
7856 return SDValue();
7900 return FoldIntToFPToInt(N, DAG);
78577901 }
78587902
78597903 SDValue DAGCombiner::visitFP_TO_UINT(SDNode *N) {
78657909 if (N0CFP)
78667910 return DAG.getNode(ISD::FP_TO_UINT, SDLoc(N), VT, N0);
78677911
7868 return SDValue();
7912 return FoldIntToFPToInt(N, DAG);
78697913 }
78707914
78717915 SDValue DAGCombiner::visitFP_ROUND(SDNode *N) {
153153 ; SPARC64: fitod
154154 ; SPARC64: fdtoi
155155
156 define void @test_itod_dtoi(i32 %a, i32* %ptr0, double* %ptr1) {
156 define void @test_itod_dtoi(i32 %a, double %b, i32* %ptr0, double* %ptr1) {
157157 entry:
158158 %0 = sitofp i32 %a to double
159159 store double %0, double* %ptr1, align 8
160 %1 = fptosi double %0 to i32
160 %1 = fptosi double %b to i32
161161 store i32 %1, i32* %ptr0, align 8
162162 ret void
163163 }
181181 }
182182
183183 ; HARD-LABEL: test_itoq_qtoi
184 ; HARD: call _Q_lltoq
185 ; HARD: call _Q_qtoll
186 ; HARD: fitoq
187 ; HARD: fqtoi
184 ; HARD-DAG: call _Q_lltoq
185 ; HARD-DAG: call _Q_qtoll
186 ; HARD-DAG: fitoq
187 ; HARD-DAG: fqtoi
188188
189189 ; SOFT-LABEL: test_itoq_qtoi
190 ; SOFT: call _Q_lltoq
191 ; SOFT: call _Q_qtoll
192 ; SOFT: call _Q_itoq
193 ; SOFT: call _Q_qtoi
194
195 define void @test_itoq_qtoi(i64 %a, i32 %b, i64* %ptr0, fp128* %ptr1) {
190 ; SOFT-DAG: call _Q_lltoq
191 ; SOFT-DAG: call _Q_qtoll
192 ; SOFT-DAG: call _Q_itoq
193 ; SOFT-DAG: call _Q_qtoi
194
195 define void @test_itoq_qtoi(i64 %a, i32 %b, fp128* %c, fp128* %d, i64* %ptr0, fp128* %ptr1) {
196196 entry:
197197 %0 = sitofp i64 %a to fp128
198198 store fp128 %0, fp128* %ptr1, align 8
199 %1 = fptosi fp128 %0 to i64
199 %cval = load fp128* %c, align 8
200 %1 = fptosi fp128 %cval to i64
200201 store i64 %1, i64* %ptr0, align 8
201202 %2 = sitofp i32 %b to fp128
202203 store fp128 %2, fp128* %ptr1, align 8
203 %3 = fptosi fp128 %2 to i32
204 %dval = load fp128* %d, align 8
205 %3 = fptosi fp128 %dval to i32
204206 %4 = bitcast i64* %ptr0 to i32*
205207 store i32 %3, i32* %4, align 8
206208 ret void
218220 ; SOFT-DAG: call _Q_utoq
219221 ; SOFT-DAG: call _Q_qtou
220222
221 define void @test_utoq_qtou(i64 %a, i32 %b, i64* %ptr0, fp128* %ptr1) {
223 define void @test_utoq_qtou(i64 %a, i32 %b, fp128* %c, fp128* %d, i64* %ptr0, fp128* %ptr1) {
222224 entry:
223225 %0 = uitofp i64 %a to fp128
224226 store fp128 %0, fp128* %ptr1, align 8
225 %1 = fptoui fp128 %0 to i64
227 %cval = load fp128* %c, align 8
228 %1 = fptoui fp128 %cval to i64
226229 store i64 %1, i64* %ptr0, align 8
227230 %2 = uitofp i32 %b to fp128
228231 store fp128 %2, fp128* %ptr1, align 8
229 %3 = fptoui fp128 %2 to i32
232 %dval = load fp128* %d, align 8
233 %3 = fptoui fp128 %dval to i32
230234 %4 = bitcast i64* %ptr0 to i32*
231235 store i32 %3, i32* %4, align 8
232236 ret void
0 ; RUN: llc -mcpu=x86-64 < %s | FileCheck %s
1
2 ; Make sure the float conversion is folded away as it should be.
3 ; CHECK-LABEL: foo
4 ; CHECK-NOT: cvt
5 ; CHECK: movzbl
6 define i32 @foo(i8 %a) #0 {
7 %conv = uitofp i8 %a to float
8 %conv1 = fptosi float %conv to i32
9 ret i32 %conv1
10 }
11
12 ; CHECK-LABEL: foo2
13 ; CHECK-NOT: cvt
14 ; CHECK: movsbl
15 define i32 @foo2(i8 %a) #0 {
16 %conv = sitofp i8 %a to float
17 %conv1 = fptosi float %conv to i32
18 ret i32 %conv1
19 }
20
21 ; CHECK-LABEL: bar
22 ; CHECK-NOT: cvt
23 ; CHECK: movl
24 define zeroext i8 @bar(i8 zeroext %a) #0 {
25 %conv = uitofp i8 %a to float
26 %conv1 = fptoui float %conv to i8
27 ret i8 %conv1
28 }
29
30 attributes #0 = { nounwind ssp uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
31