llvm.org GIT mirror llvm / 9264039
Do not try to use i8 and i16 versions of FP_TO_U/SINT soft float library calls It appears that neither compiler-rt nor the gnu soft-float libraries actually implement these conversions. Instead of emitting calls to library functions that don't exist, handle it similarly to the way we handle i8 -> float and i16 -> float conversions: call the i32 library function, and adjust the type. Differential Revision: http://reviews.llvm.org/D15151 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@255643 91177308-0d34-0410-b5e6-96231b3b80d8 Michael Kuperstein 4 years ago
5 changed file(s) with 64 addition(s) and 48 deletion(s). Raw diff Collapse all Expand all
230230 FPROUND_F80_F64,
231231 FPROUND_F128_F64,
232232 FPROUND_PPCF128_F64,
233 FPTOSINT_F32_I8,
234 FPTOSINT_F32_I16,
235233 FPTOSINT_F32_I32,
236234 FPTOSINT_F32_I64,
237235 FPTOSINT_F32_I128,
238 FPTOSINT_F64_I8,
239 FPTOSINT_F64_I16,
240236 FPTOSINT_F64_I32,
241237 FPTOSINT_F64_I64,
242238 FPTOSINT_F64_I128,
249245 FPTOSINT_PPCF128_I32,
250246 FPTOSINT_PPCF128_I64,
251247 FPTOSINT_PPCF128_I128,
252 FPTOUINT_F32_I8,
253 FPTOUINT_F32_I16,
254248 FPTOUINT_F32_I32,
255249 FPTOUINT_F32_I64,
256250 FPTOUINT_F32_I128,
257 FPTOUINT_F64_I8,
258 FPTOUINT_F64_I16,
259251 FPTOUINT_F64_I32,
260252 FPTOUINT_F64_I64,
261253 FPTOUINT_F64_I128,
738738 case ISD::FP_EXTEND: Res = SoftenFloatOp_FP_EXTEND(N); break;
739739 case ISD::FP_TO_FP16: // Same as FP_ROUND for softening purposes
740740 case ISD::FP_ROUND: Res = SoftenFloatOp_FP_ROUND(N); break;
741 case ISD::FP_TO_SINT: Res = SoftenFloatOp_FP_TO_SINT(N); break;
742 case ISD::FP_TO_UINT: Res = SoftenFloatOp_FP_TO_UINT(N); break;
741 case ISD::FP_TO_SINT:
742 case ISD::FP_TO_UINT: Res = SoftenFloatOp_FP_TO_XINT(N); break;
743743 case ISD::SELECT_CC: Res = SoftenFloatOp_SELECT_CC(N); break;
744744 case ISD::SETCC: Res = SoftenFloatOp_SETCC(N); break;
745745 case ISD::STORE:
864864 0);
865865 }
866866
867 SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_SINT(SDNode *N) {
867 SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_XINT(SDNode *N) {
868 bool Signed = N->getOpcode() == ISD::FP_TO_SINT;
869 EVT SVT = N->getOperand(0).getValueType();
868870 EVT RVT = N->getValueType(0);
869 RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT);
870 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_SINT!");
871 EVT NVT = EVT();
872 SDLoc dl(N);
873
874 // If the result is not legal, eg: fp -> i1, then it needs to be promoted to
875 // a larger type, eg: fp -> i32. Even if it is legal, no libcall may exactly
876 // match, eg. we don't have fp -> i8 conversions.
877 // Look for an appropriate libcall.
878 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
879 for (unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE;
880 IntVT <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL;
881 ++IntVT) {
882 NVT = (MVT::SimpleValueType)IntVT;
883 // The type needs to big enough to hold the result.
884 if (NVT.bitsGE(RVT))
885 LC = Signed ? RTLIB::getFPTOSINT(SVT, NVT):RTLIB::getFPTOUINT(SVT, NVT);
886 }
887 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_XINT!");
888
871889 SDValue Op = GetSoftenedFloat(N->getOperand(0));
872 return TLI.makeLibCall(DAG, LC, RVT, Op, false, SDLoc(N)).first;
873 }
874
875 SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_UINT(SDNode *N) {
876 EVT RVT = N->getValueType(0);
877 RTLIB::Libcall LC = RTLIB::getFPTOUINT(N->getOperand(0).getValueType(), RVT);
878 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_UINT!");
879 SDValue Op = GetSoftenedFloat(N->getOperand(0));
880 return TLI.makeLibCall(DAG, LC, RVT, Op, false, SDLoc(N)).first;
890 SDValue Res = TLI.makeLibCall(DAG, LC, NVT, Op, false, dl).first;
891
892 // Truncate the result if the libcall returns a larger type.
893 return DAG.getNode(ISD::TRUNCATE, dl, RVT, Res);
881894 }
882895
883896 SDValue DAGTypeLegalizer::SoftenFloatOp_SELECT_CC(SDNode *N) {
477477 SDValue SoftenFloatOp_BR_CC(SDNode *N);
478478 SDValue SoftenFloatOp_FP_EXTEND(SDNode *N);
479479 SDValue SoftenFloatOp_FP_ROUND(SDNode *N);
480 SDValue SoftenFloatOp_FP_TO_SINT(SDNode *N);
481 SDValue SoftenFloatOp_FP_TO_UINT(SDNode *N);
480 SDValue SoftenFloatOp_FP_TO_XINT(SDNode *N);
482481 SDValue SoftenFloatOp_SELECT_CC(SDNode *N);
483482 SDValue SoftenFloatOp_SETCC(SDNode *N);
484483 SDValue SoftenFloatOp_STORE(SDNode *N, unsigned OpNo);
246246 Names[RTLIB::FPROUND_F80_F64] = "__truncxfdf2";
247247 Names[RTLIB::FPROUND_F128_F64] = "__trunctfdf2";
248248 Names[RTLIB::FPROUND_PPCF128_F64] = "__trunctfdf2";
249 Names[RTLIB::FPTOSINT_F32_I8] = "__fixsfqi";
250 Names[RTLIB::FPTOSINT_F32_I16] = "__fixsfhi";
251249 Names[RTLIB::FPTOSINT_F32_I32] = "__fixsfsi";
252250 Names[RTLIB::FPTOSINT_F32_I64] = "__fixsfdi";
253251 Names[RTLIB::FPTOSINT_F32_I128] = "__fixsfti";
254 Names[RTLIB::FPTOSINT_F64_I8] = "__fixdfqi";
255 Names[RTLIB::FPTOSINT_F64_I16] = "__fixdfhi";
256252 Names[RTLIB::FPTOSINT_F64_I32] = "__fixdfsi";
257253 Names[RTLIB::FPTOSINT_F64_I64] = "__fixdfdi";
258254 Names[RTLIB::FPTOSINT_F64_I128] = "__fixdfti";
265261 Names[RTLIB::FPTOSINT_PPCF128_I32] = "__fixtfsi";
266262 Names[RTLIB::FPTOSINT_PPCF128_I64] = "__fixtfdi";
267263 Names[RTLIB::FPTOSINT_PPCF128_I128] = "__fixtfti";
268 Names[RTLIB::FPTOUINT_F32_I8] = "__fixunssfqi";
269 Names[RTLIB::FPTOUINT_F32_I16] = "__fixunssfhi";
270264 Names[RTLIB::FPTOUINT_F32_I32] = "__fixunssfsi";
271265 Names[RTLIB::FPTOUINT_F32_I64] = "__fixunssfdi";
272266 Names[RTLIB::FPTOUINT_F32_I128] = "__fixunssfti";
273 Names[RTLIB::FPTOUINT_F64_I8] = "__fixunsdfqi";
274 Names[RTLIB::FPTOUINT_F64_I16] = "__fixunsdfhi";
275267 Names[RTLIB::FPTOUINT_F64_I32] = "__fixunsdfsi";
276268 Names[RTLIB::FPTOUINT_F64_I64] = "__fixunsdfdi";
277269 Names[RTLIB::FPTOUINT_F64_I128] = "__fixunsdfti";
500492 /// UNKNOWN_LIBCALL if there is none.
501493 RTLIB::Libcall RTLIB::getFPTOSINT(EVT OpVT, EVT RetVT) {
502494 if (OpVT == MVT::f32) {
503 if (RetVT == MVT::i8)
504 return FPTOSINT_F32_I8;
505 if (RetVT == MVT::i16)
506 return FPTOSINT_F32_I16;
507495 if (RetVT == MVT::i32)
508496 return FPTOSINT_F32_I32;
509497 if (RetVT == MVT::i64)
511499 if (RetVT == MVT::i128)
512500 return FPTOSINT_F32_I128;
513501 } else if (OpVT == MVT::f64) {
514 if (RetVT == MVT::i8)
515 return FPTOSINT_F64_I8;
516 if (RetVT == MVT::i16)
517 return FPTOSINT_F64_I16;
518502 if (RetVT == MVT::i32)
519503 return FPTOSINT_F64_I32;
520504 if (RetVT == MVT::i64)
550534 /// UNKNOWN_LIBCALL if there is none.
551535 RTLIB::Libcall RTLIB::getFPTOUINT(EVT OpVT, EVT RetVT) {
552536 if (OpVT == MVT::f32) {
553 if (RetVT == MVT::i8)
554 return FPTOUINT_F32_I8;
555 if (RetVT == MVT::i16)
556 return FPTOUINT_F32_I16;
557537 if (RetVT == MVT::i32)
558538 return FPTOUINT_F32_I32;
559539 if (RetVT == MVT::i64)
561541 if (RetVT == MVT::i128)
562542 return FPTOUINT_F32_I128;
563543 } else if (OpVT == MVT::f64) {
564 if (RetVT == MVT::i8)
565 return FPTOUINT_F64_I8;
566 if (RetVT == MVT::i16)
567 return FPTOUINT_F64_I16;
568544 if (RetVT == MVT::i32)
569545 return FPTOUINT_F64_I32;
570546 if (RetVT == MVT::i64)
129129 ret i32 %conv
130130 }
131131
132 ; CHECK-LABEL: f_to_s8:
133 ; CHECK: call{{l|q}} __fixsfsi
134 define i8 @f_to_s8(float %f, i8 %i) #0 {
135 entry:
136 %conv = fptosi float %f to i8
137 %add = add i8 %conv, %i
138 ret i8 %add
139 }
140
141 ; CHECK-LABEL: f_to_u8:
142 ; CHECK: call{{l|q}} __fixunssfsi
143 define i8 @f_to_u8(float %f, i8 %i) #0 {
144 entry:
145 %conv = fptoui float %f to i8
146 %add = add i8 %conv, %i
147 ret i8 %add
148 }
149
150 ; CHECK-LABEL: f_to_s16:
151 ; CHECK: call{{l|q}} __fixsfsi
152 define i16 @f_to_s16(float %f, i16 %i) #0 {
153 entry:
154 %conv = fptosi float %f to i16
155 %add = add i16 %conv, %i
156 ret i16 %add
157 }
158
159 ; CHECK-LABEL: f_to_u16:
160 ; CHECK: call{{l|q}} __fixunssfsi
161 define i16 @f_to_u16(float %f, i16 %i) #0 {
162 entry:
163 %conv = fptoui float %f to i16
164 %add = add i16 %conv, %i
165 ret i16 %add
166 }
167
132168 attributes #0 = { nounwind "use-soft-float"="true" }