From: Craig Topper Date: Wed, 7 Dec 2022 19:58:30 +0000 (-0800) Subject: [RISCV] Promote f16 fp_to_int_sat with Zfhmin during lowering instead of isel. X-Git-Tag: upstream/17.0.6~24895 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e3540fb9482962a5a70d88e4a93843d1d4f6096d;p=platform%2Fupstream%2Fllvm.git [RISCV] Promote f16 fp_to_int_sat with Zfhmin during lowering instead of isel. We already have a custom handler for FP_TO_(S/U)INT_SAT. It's easy enought to inject an FP_EXTEND in there. --- diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 0613a76..6eb85d4 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -1959,6 +1959,11 @@ static SDValue lowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG, bool IsSigned = Op.getOpcode() == ISD::FP_TO_SINT_SAT; if (!DstVT.isVector()) { + // In absense, of Zfh, promote f16 to f32, then saturate the result. + if (Src.getSimpleValueType() == MVT::f16 && !Subtarget.hasStdExtZfh()) { + Src = DAG.getNode(ISD::FP_EXTEND, SDLoc(Op), MVT::f32, Src); + } + unsigned Opc; if (SatVT == DstVT) Opc = IsSigned ? RISCVISD::FCVT_X : RISCVISD::FCVT_XU; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td index 086d31e..f50bb59 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td @@ -370,7 +370,7 @@ let Predicates = [HasStdExtZfh, IsRV32] in { def : Pat<(i32 (any_fp_to_sint FPR16:$rs1)), (FCVT_W_H $rs1, 0b001)>; def : Pat<(i32 (any_fp_to_uint FPR16:$rs1)), (FCVT_WU_H $rs1, 0b001)>; -// Saturating float->[u]int32. +// Saturating half->[u]int32. def : Pat<(i32 (riscv_fcvt_x FPR16:$rs1, timm:$frm)), (FCVT_W_H $rs1, timm:$frm)>; def : Pat<(i32 (riscv_fcvt_xu FPR16:$rs1, timm:$frm)), (FCVT_WU_H $rs1, timm:$frm)>; @@ -396,7 +396,7 @@ def : Pat<(riscv_any_fcvt_wu_rv64 FPR16:$rs1, timm:$frm), (FCVT_WU_H $rs1, timm: def : Pat<(i64 (any_fp_to_sint FPR16:$rs1)), (FCVT_L_H $rs1, 0b001)>; def : Pat<(i64 (any_fp_to_uint FPR16:$rs1)), (FCVT_LU_H $rs1, 0b001)>; -// Saturating float->[u]int64. +// Saturating half->[u]int64. def : Pat<(i64 (riscv_fcvt_x FPR16:$rs1, timm:$frm)), (FCVT_L_H $rs1, timm:$frm)>; def : Pat<(i64 (riscv_fcvt_xu FPR16:$rs1, timm:$frm)), (FCVT_LU_H $rs1, timm:$frm)>; @@ -446,10 +446,6 @@ def : Pat<(i32 (any_lround FPR16:$rs1)), (FCVT_W_S (FCVT_S_H $rs1), 0b100)>; // [u]int->half. Match GCC and default to using dynamic rounding mode. def : Pat<(any_sint_to_fp (i32 GPR:$rs1)), (FCVT_H_S (FCVT_S_W $rs1, 0b111), 0b111)>; def : Pat<(any_uint_to_fp (i32 GPR:$rs1)), (FCVT_H_S (FCVT_S_WU $rs1, 0b111), 0b111)>; - -// Saturating float->[u]int32. -def : Pat<(i32 (riscv_fcvt_x FPR16:$rs1, timm:$frm)), (FCVT_W_S (FCVT_S_H $rs1), timm:$frm)>; -def : Pat<(i32 (riscv_fcvt_xu FPR16:$rs1, timm:$frm)), (FCVT_WU_S (FCVT_S_H $rs1), timm:$frm)>; } // Predicates = [HasStdExtZfhmin, NoStdExtZfh, IsRV32] let Predicates = [HasStdExtZfhmin, NoStdExtZfh, IsRV64] in { @@ -469,10 +465,6 @@ def : Pat<(i64 (any_llround FPR16:$rs1)), (FCVT_L_S (FCVT_S_H $rs1), 0b100)>; def : Pat<(any_sint_to_fp (i64 GPR:$rs1)), (FCVT_H_S (FCVT_S_L $rs1, 0b111), 0b111)>; def : Pat<(any_uint_to_fp (i64 GPR:$rs1)), (FCVT_H_S (FCVT_S_LU $rs1, 0b111), 0b111)>; -// Saturating float->[u]int64. -def : Pat<(i64 (riscv_fcvt_x FPR16:$rs1, timm:$frm)), (FCVT_L_S (FCVT_S_H $rs1), timm:$frm)>; -def : Pat<(i64 (riscv_fcvt_xu FPR16:$rs1, timm:$frm)), (FCVT_LU_S (FCVT_S_H $rs1), timm:$frm)>; - def : Pat<(riscv_any_fcvt_w_rv64 FPR16:$rs1, timm:$frm), (FCVT_W_S (FCVT_S_H $rs1), timm:$frm)>; def : Pat<(riscv_any_fcvt_wu_rv64 FPR16:$rs1, timm:$frm), (FCVT_WU_S (FCVT_S_H $rs1), timm:$frm)>; } // Predicates = [HasStdExtZfhmin, NoStdExtZfh, IsRV64]