mirror of
https://github.com/RPCSX/llvm.git
synced 2025-01-24 21:25:41 +00:00
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
This commit is contained in:
parent
eaa28289cd
commit
926403958d
@ -231,13 +231,9 @@ namespace RTLIB {
|
||||
FPROUND_F80_F64,
|
||||
FPROUND_F128_F64,
|
||||
FPROUND_PPCF128_F64,
|
||||
FPTOSINT_F32_I8,
|
||||
FPTOSINT_F32_I16,
|
||||
FPTOSINT_F32_I32,
|
||||
FPTOSINT_F32_I64,
|
||||
FPTOSINT_F32_I128,
|
||||
FPTOSINT_F64_I8,
|
||||
FPTOSINT_F64_I16,
|
||||
FPTOSINT_F64_I32,
|
||||
FPTOSINT_F64_I64,
|
||||
FPTOSINT_F64_I128,
|
||||
@ -250,13 +246,9 @@ namespace RTLIB {
|
||||
FPTOSINT_PPCF128_I32,
|
||||
FPTOSINT_PPCF128_I64,
|
||||
FPTOSINT_PPCF128_I128,
|
||||
FPTOUINT_F32_I8,
|
||||
FPTOUINT_F32_I16,
|
||||
FPTOUINT_F32_I32,
|
||||
FPTOUINT_F32_I64,
|
||||
FPTOUINT_F32_I128,
|
||||
FPTOUINT_F64_I8,
|
||||
FPTOUINT_F64_I16,
|
||||
FPTOUINT_F64_I32,
|
||||
FPTOUINT_F64_I64,
|
||||
FPTOUINT_F64_I128,
|
||||
|
@ -739,8 +739,8 @@ bool DAGTypeLegalizer::SoftenFloatOperand(SDNode *N, unsigned OpNo) {
|
||||
case ISD::FP_EXTEND: Res = SoftenFloatOp_FP_EXTEND(N); break;
|
||||
case ISD::FP_TO_FP16: // Same as FP_ROUND for softening purposes
|
||||
case ISD::FP_ROUND: Res = SoftenFloatOp_FP_ROUND(N); break;
|
||||
case ISD::FP_TO_SINT: Res = SoftenFloatOp_FP_TO_SINT(N); break;
|
||||
case ISD::FP_TO_UINT: Res = SoftenFloatOp_FP_TO_UINT(N); break;
|
||||
case ISD::FP_TO_SINT:
|
||||
case ISD::FP_TO_UINT: Res = SoftenFloatOp_FP_TO_XINT(N); break;
|
||||
case ISD::SELECT_CC: Res = SoftenFloatOp_SELECT_CC(N); break;
|
||||
case ISD::SETCC: Res = SoftenFloatOp_SETCC(N); break;
|
||||
case ISD::STORE:
|
||||
@ -865,20 +865,33 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_BR_CC(SDNode *N) {
|
||||
0);
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_SINT(SDNode *N) {
|
||||
SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_XINT(SDNode *N) {
|
||||
bool Signed = N->getOpcode() == ISD::FP_TO_SINT;
|
||||
EVT SVT = N->getOperand(0).getValueType();
|
||||
EVT RVT = N->getValueType(0);
|
||||
RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT);
|
||||
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_SINT!");
|
||||
SDValue Op = GetSoftenedFloat(N->getOperand(0));
|
||||
return TLI.makeLibCall(DAG, LC, RVT, Op, false, SDLoc(N)).first;
|
||||
}
|
||||
EVT NVT = EVT();
|
||||
SDLoc dl(N);
|
||||
|
||||
// If the result is not legal, eg: fp -> i1, then it needs to be promoted to
|
||||
// a larger type, eg: fp -> i32. Even if it is legal, no libcall may exactly
|
||||
// match, eg. we don't have fp -> i8 conversions.
|
||||
// Look for an appropriate libcall.
|
||||
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
|
||||
for (unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE;
|
||||
IntVT <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL;
|
||||
++IntVT) {
|
||||
NVT = (MVT::SimpleValueType)IntVT;
|
||||
// The type needs to big enough to hold the result.
|
||||
if (NVT.bitsGE(RVT))
|
||||
LC = Signed ? RTLIB::getFPTOSINT(SVT, NVT):RTLIB::getFPTOUINT(SVT, NVT);
|
||||
}
|
||||
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_XINT!");
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_UINT(SDNode *N) {
|
||||
EVT RVT = N->getValueType(0);
|
||||
RTLIB::Libcall LC = RTLIB::getFPTOUINT(N->getOperand(0).getValueType(), RVT);
|
||||
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_UINT!");
|
||||
SDValue Op = GetSoftenedFloat(N->getOperand(0));
|
||||
return TLI.makeLibCall(DAG, LC, RVT, Op, false, SDLoc(N)).first;
|
||||
SDValue Res = TLI.makeLibCall(DAG, LC, NVT, Op, false, dl).first;
|
||||
|
||||
// Truncate the result if the libcall returns a larger type.
|
||||
return DAG.getNode(ISD::TRUNCATE, dl, RVT, Res);
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftenFloatOp_SELECT_CC(SDNode *N) {
|
||||
|
@ -478,8 +478,7 @@ private:
|
||||
SDValue SoftenFloatOp_BR_CC(SDNode *N);
|
||||
SDValue SoftenFloatOp_FP_EXTEND(SDNode *N);
|
||||
SDValue SoftenFloatOp_FP_ROUND(SDNode *N);
|
||||
SDValue SoftenFloatOp_FP_TO_SINT(SDNode *N);
|
||||
SDValue SoftenFloatOp_FP_TO_UINT(SDNode *N);
|
||||
SDValue SoftenFloatOp_FP_TO_XINT(SDNode *N);
|
||||
SDValue SoftenFloatOp_SELECT_CC(SDNode *N);
|
||||
SDValue SoftenFloatOp_SETCC(SDNode *N);
|
||||
SDValue SoftenFloatOp_STORE(SDNode *N, unsigned OpNo);
|
||||
|
@ -247,13 +247,9 @@ static void InitLibcallNames(const char **Names, const Triple &TT) {
|
||||
Names[RTLIB::FPROUND_F80_F64] = "__truncxfdf2";
|
||||
Names[RTLIB::FPROUND_F128_F64] = "__trunctfdf2";
|
||||
Names[RTLIB::FPROUND_PPCF128_F64] = "__trunctfdf2";
|
||||
Names[RTLIB::FPTOSINT_F32_I8] = "__fixsfqi";
|
||||
Names[RTLIB::FPTOSINT_F32_I16] = "__fixsfhi";
|
||||
Names[RTLIB::FPTOSINT_F32_I32] = "__fixsfsi";
|
||||
Names[RTLIB::FPTOSINT_F32_I64] = "__fixsfdi";
|
||||
Names[RTLIB::FPTOSINT_F32_I128] = "__fixsfti";
|
||||
Names[RTLIB::FPTOSINT_F64_I8] = "__fixdfqi";
|
||||
Names[RTLIB::FPTOSINT_F64_I16] = "__fixdfhi";
|
||||
Names[RTLIB::FPTOSINT_F64_I32] = "__fixdfsi";
|
||||
Names[RTLIB::FPTOSINT_F64_I64] = "__fixdfdi";
|
||||
Names[RTLIB::FPTOSINT_F64_I128] = "__fixdfti";
|
||||
@ -266,13 +262,9 @@ static void InitLibcallNames(const char **Names, const Triple &TT) {
|
||||
Names[RTLIB::FPTOSINT_PPCF128_I32] = "__fixtfsi";
|
||||
Names[RTLIB::FPTOSINT_PPCF128_I64] = "__fixtfdi";
|
||||
Names[RTLIB::FPTOSINT_PPCF128_I128] = "__fixtfti";
|
||||
Names[RTLIB::FPTOUINT_F32_I8] = "__fixunssfqi";
|
||||
Names[RTLIB::FPTOUINT_F32_I16] = "__fixunssfhi";
|
||||
Names[RTLIB::FPTOUINT_F32_I32] = "__fixunssfsi";
|
||||
Names[RTLIB::FPTOUINT_F32_I64] = "__fixunssfdi";
|
||||
Names[RTLIB::FPTOUINT_F32_I128] = "__fixunssfti";
|
||||
Names[RTLIB::FPTOUINT_F64_I8] = "__fixunsdfqi";
|
||||
Names[RTLIB::FPTOUINT_F64_I16] = "__fixunsdfhi";
|
||||
Names[RTLIB::FPTOUINT_F64_I32] = "__fixunsdfsi";
|
||||
Names[RTLIB::FPTOUINT_F64_I64] = "__fixunsdfdi";
|
||||
Names[RTLIB::FPTOUINT_F64_I128] = "__fixunsdfti";
|
||||
@ -501,10 +493,6 @@ RTLIB::Libcall RTLIB::getFPROUND(EVT OpVT, EVT RetVT) {
|
||||
/// UNKNOWN_LIBCALL if there is none.
|
||||
RTLIB::Libcall RTLIB::getFPTOSINT(EVT OpVT, EVT RetVT) {
|
||||
if (OpVT == MVT::f32) {
|
||||
if (RetVT == MVT::i8)
|
||||
return FPTOSINT_F32_I8;
|
||||
if (RetVT == MVT::i16)
|
||||
return FPTOSINT_F32_I16;
|
||||
if (RetVT == MVT::i32)
|
||||
return FPTOSINT_F32_I32;
|
||||
if (RetVT == MVT::i64)
|
||||
@ -512,10 +500,6 @@ RTLIB::Libcall RTLIB::getFPTOSINT(EVT OpVT, EVT RetVT) {
|
||||
if (RetVT == MVT::i128)
|
||||
return FPTOSINT_F32_I128;
|
||||
} else if (OpVT == MVT::f64) {
|
||||
if (RetVT == MVT::i8)
|
||||
return FPTOSINT_F64_I8;
|
||||
if (RetVT == MVT::i16)
|
||||
return FPTOSINT_F64_I16;
|
||||
if (RetVT == MVT::i32)
|
||||
return FPTOSINT_F64_I32;
|
||||
if (RetVT == MVT::i64)
|
||||
@ -551,10 +535,6 @@ RTLIB::Libcall RTLIB::getFPTOSINT(EVT OpVT, EVT RetVT) {
|
||||
/// UNKNOWN_LIBCALL if there is none.
|
||||
RTLIB::Libcall RTLIB::getFPTOUINT(EVT OpVT, EVT RetVT) {
|
||||
if (OpVT == MVT::f32) {
|
||||
if (RetVT == MVT::i8)
|
||||
return FPTOUINT_F32_I8;
|
||||
if (RetVT == MVT::i16)
|
||||
return FPTOUINT_F32_I16;
|
||||
if (RetVT == MVT::i32)
|
||||
return FPTOUINT_F32_I32;
|
||||
if (RetVT == MVT::i64)
|
||||
@ -562,10 +542,6 @@ RTLIB::Libcall RTLIB::getFPTOUINT(EVT OpVT, EVT RetVT) {
|
||||
if (RetVT == MVT::i128)
|
||||
return FPTOUINT_F32_I128;
|
||||
} else if (OpVT == MVT::f64) {
|
||||
if (RetVT == MVT::i8)
|
||||
return FPTOUINT_F64_I8;
|
||||
if (RetVT == MVT::i16)
|
||||
return FPTOUINT_F64_I16;
|
||||
if (RetVT == MVT::i32)
|
||||
return FPTOUINT_F64_I32;
|
||||
if (RetVT == MVT::i64)
|
||||
|
@ -130,4 +130,40 @@ entry:
|
||||
ret i32 %conv
|
||||
}
|
||||
|
||||
; CHECK-LABEL: f_to_s8:
|
||||
; CHECK: call{{l|q}} __fixsfsi
|
||||
define i8 @f_to_s8(float %f, i8 %i) #0 {
|
||||
entry:
|
||||
%conv = fptosi float %f to i8
|
||||
%add = add i8 %conv, %i
|
||||
ret i8 %add
|
||||
}
|
||||
|
||||
; CHECK-LABEL: f_to_u8:
|
||||
; CHECK: call{{l|q}} __fixunssfsi
|
||||
define i8 @f_to_u8(float %f, i8 %i) #0 {
|
||||
entry:
|
||||
%conv = fptoui float %f to i8
|
||||
%add = add i8 %conv, %i
|
||||
ret i8 %add
|
||||
}
|
||||
|
||||
; CHECK-LABEL: f_to_s16:
|
||||
; CHECK: call{{l|q}} __fixsfsi
|
||||
define i16 @f_to_s16(float %f, i16 %i) #0 {
|
||||
entry:
|
||||
%conv = fptosi float %f to i16
|
||||
%add = add i16 %conv, %i
|
||||
ret i16 %add
|
||||
}
|
||||
|
||||
; CHECK-LABEL: f_to_u16:
|
||||
; CHECK: call{{l|q}} __fixunssfsi
|
||||
define i16 @f_to_u16(float %f, i16 %i) #0 {
|
||||
entry:
|
||||
%conv = fptoui float %f to i16
|
||||
%add = add i16 %conv, %i
|
||||
ret i16 %add
|
||||
}
|
||||
|
||||
attributes #0 = { nounwind "use-soft-float"="true" }
|
||||
|
Loading…
x
Reference in New Issue
Block a user