[RISCV] Promote f16 fp_to_int_sat with Zfhmin during lowering instead of isel.
authorCraig Topper <craig.topper@sifive.com>
Wed, 7 Dec 2022 19:58:30 +0000 (11:58 -0800)
committerCraig Topper <craig.topper@sifive.com>
Wed, 7 Dec 2022 19:58:30 +0000 (11:58 -0800)
We already have a custom handler for FP_TO_(S/U)INT_SAT. It's easy
enought to inject an FP_EXTEND in there.

llvm/lib/Target/RISCV/RISCVISelLowering.cpp
llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td

index 0613a76..6eb85d4 100644 (file)
@@ -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;
index 086d31e..f50bb59 100644 (file)
@@ -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]