1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

[Legalizer] Promote result type in expanding FP_TO_XINT

This patch promotes result integer type of FP_TO_XINT in expanding.
So crash in conversion from ppc_fp128 to i1 will be fixed.

Reviewed By: steven.zhang

Differential Revision: https://reviews.llvm.org/D92473
This commit is contained in:
Qiu Chaofan 2021-01-18 11:56:11 +08:00
parent 0b832ca92a
commit 6cc3cf5799
2 changed files with 123 additions and 14 deletions

View File

@ -913,6 +913,24 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_BR_CC(SDNode *N) {
0);
}
// Even if the result type is legal, no libcall may exactly match. (e.g. We
// don't have FP-i8 conversions) This helper method looks for an appropriate
// promoted libcall.
static RTLIB::Libcall findFPToIntLibcall(EVT SrcVT, EVT RetVT, EVT &Promoted,
bool Signed) {
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
for (unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE;
IntVT <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL;
++IntVT) {
Promoted = (MVT::SimpleValueType)IntVT;
// The type needs to big enough to hold the result.
if (Promoted.bitsGE(RetVT))
LC = Signed ? RTLIB::getFPTOSINT(SrcVT, Promoted)
: RTLIB::getFPTOUINT(SrcVT, Promoted);
}
return LC;
}
SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_XINT(SDNode *N) {
bool IsStrict = N->isStrictFPOpcode();
bool Signed = N->getOpcode() == ISD::FP_TO_SINT ||
@ -928,16 +946,9 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_XINT(SDNode *N) {
// 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!");
RTLIB::Libcall LC = findFPToIntLibcall(SVT, RVT, NVT, Signed);
assert(LC != RTLIB::UNKNOWN_LIBCALL && NVT.isSimple() &&
"Unsupported FP_TO_XINT!");
Op = GetSoftenedFloat(Op);
SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
@ -1895,12 +1906,14 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_XINT(SDNode *N) {
N->getOpcode() == ISD::STRICT_FP_TO_SINT;
SDValue Op = N->getOperand(IsStrict ? 1 : 0);
SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
RTLIB::Libcall LC = Signed ? RTLIB::getFPTOSINT(Op.getValueType(), RVT)
: RTLIB::getFPTOUINT(Op.getValueType(), RVT);
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_XINT!");
EVT NVT;
RTLIB::Libcall LC = findFPToIntLibcall(Op.getValueType(), RVT, NVT, Signed);
assert(LC != RTLIB::UNKNOWN_LIBCALL && NVT.isSimple() &&
"Unsupported FP_TO_XINT!");
TargetLowering::MakeLibCallOptions CallOptions;
std::pair<SDValue, SDValue> Tmp =
TLI.makeLibCall(DAG, LC, RVT, Op, CallOptions, dl, Chain);
TLI.makeLibCall(DAG, LC, NVT, Op, CallOptions, dl, Chain);
if (!IsStrict)
return Tmp.first;

View File

@ -1975,6 +1975,100 @@ entry:
ret ppc_fp128 %conv
}
define i1 @ppcq_to_s1(ppc_fp128 %a) {
; PC64LE-LABEL: ppcq_to_s1:
; PC64LE: # %bb.0: # %entry
; PC64LE-NEXT: mflr 0
; PC64LE-NEXT: std 0, 16(1)
; PC64LE-NEXT: stdu 1, -32(1)
; PC64LE-NEXT: .cfi_def_cfa_offset 32
; PC64LE-NEXT: .cfi_offset lr, 16
; PC64LE-NEXT: bl __gcc_qtou
; PC64LE-NEXT: nop
; PC64LE-NEXT: addi 1, 1, 32
; PC64LE-NEXT: ld 0, 16(1)
; PC64LE-NEXT: mtlr 0
; PC64LE-NEXT: blr
;
; PC64LE9-LABEL: ppcq_to_s1:
; PC64LE9: # %bb.0: # %entry
; PC64LE9-NEXT: mflr 0
; PC64LE9-NEXT: std 0, 16(1)
; PC64LE9-NEXT: stdu 1, -32(1)
; PC64LE9-NEXT: .cfi_def_cfa_offset 32
; PC64LE9-NEXT: .cfi_offset lr, 16
; PC64LE9-NEXT: bl __gcc_qtou
; PC64LE9-NEXT: nop
; PC64LE9-NEXT: addi 1, 1, 32
; PC64LE9-NEXT: ld 0, 16(1)
; PC64LE9-NEXT: mtlr 0
; PC64LE9-NEXT: blr
;
; PC64-LABEL: ppcq_to_s1:
; PC64: # %bb.0: # %entry
; PC64-NEXT: mflr 0
; PC64-NEXT: std 0, 16(1)
; PC64-NEXT: stdu 1, -112(1)
; PC64-NEXT: .cfi_def_cfa_offset 112
; PC64-NEXT: .cfi_offset lr, 16
; PC64-NEXT: bl __gcc_qtou
; PC64-NEXT: nop
; PC64-NEXT: addi 1, 1, 112
; PC64-NEXT: ld 0, 16(1)
; PC64-NEXT: mtlr 0
; PC64-NEXT: blr
entry:
%conv = tail call i1 @llvm.experimental.constrained.fptosi.ppcf128.i1(ppc_fp128 %a, metadata !"fpexcept.strict") #1
ret i1 %conv
}
define i1 @ppcq_to_u1(ppc_fp128 %a) {
; PC64LE-LABEL: ppcq_to_u1:
; PC64LE: # %bb.0: # %entry
; PC64LE-NEXT: mflr 0
; PC64LE-NEXT: std 0, 16(1)
; PC64LE-NEXT: stdu 1, -32(1)
; PC64LE-NEXT: .cfi_def_cfa_offset 32
; PC64LE-NEXT: .cfi_offset lr, 16
; PC64LE-NEXT: bl __fixunstfsi
; PC64LE-NEXT: nop
; PC64LE-NEXT: addi 1, 1, 32
; PC64LE-NEXT: ld 0, 16(1)
; PC64LE-NEXT: mtlr 0
; PC64LE-NEXT: blr
;
; PC64LE9-LABEL: ppcq_to_u1:
; PC64LE9: # %bb.0: # %entry
; PC64LE9-NEXT: mflr 0
; PC64LE9-NEXT: std 0, 16(1)
; PC64LE9-NEXT: stdu 1, -32(1)
; PC64LE9-NEXT: .cfi_def_cfa_offset 32
; PC64LE9-NEXT: .cfi_offset lr, 16
; PC64LE9-NEXT: bl __fixunstfsi
; PC64LE9-NEXT: nop
; PC64LE9-NEXT: addi 1, 1, 32
; PC64LE9-NEXT: ld 0, 16(1)
; PC64LE9-NEXT: mtlr 0
; PC64LE9-NEXT: blr
;
; PC64-LABEL: ppcq_to_u1:
; PC64: # %bb.0: # %entry
; PC64-NEXT: mflr 0
; PC64-NEXT: std 0, 16(1)
; PC64-NEXT: stdu 1, -112(1)
; PC64-NEXT: .cfi_def_cfa_offset 112
; PC64-NEXT: .cfi_offset lr, 16
; PC64-NEXT: bl __fixunstfsi
; PC64-NEXT: nop
; PC64-NEXT: addi 1, 1, 112
; PC64-NEXT: ld 0, 16(1)
; PC64-NEXT: mtlr 0
; PC64-NEXT: blr
entry:
%conv = tail call i1 @llvm.experimental.constrained.fptoui.ppcf128.i1(ppc_fp128 %a, metadata !"fpexcept.strict") #1
ret i1 %conv
}
attributes #0 = { nounwind strictfp }
attributes #1 = { strictfp }
@ -2008,8 +2102,10 @@ declare ppc_fp128 @llvm.experimental.constrained.fsub.ppcf128(ppc_fp128, ppc_fp1
declare ppc_fp128 @llvm.experimental.constrained.trunc.ppcf128(ppc_fp128, metadata)
declare i64 @llvm.experimental.constrained.fptosi.i64.ppcf128(ppc_fp128, metadata)
declare i32 @llvm.experimental.constrained.fptosi.i32.ppcf128(ppc_fp128, metadata)
declare i1 @llvm.experimental.constrained.fptosi.ppcf128.i1(ppc_fp128, metadata)
declare i64 @llvm.experimental.constrained.fptoui.i64.ppcf128(ppc_fp128, metadata)
declare i32 @llvm.experimental.constrained.fptoui.i32.ppcf128(ppc_fp128, metadata)
declare i1 @llvm.experimental.constrained.fptoui.ppcf128.i1(ppc_fp128, metadata)
declare ppc_fp128 @llvm.experimental.constrained.sitofp.ppcf128.i32(i32, metadata, metadata)
declare ppc_fp128 @llvm.experimental.constrained.uitofp.ppcf128.i32(i32, metadata, metadata)
declare ppc_fp128 @llvm.experimental.constrained.sitofp.ppcf128.i64(i64, metadata, metadata)