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:
parent
0b832ca92a
commit
6cc3cf5799
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user