[RISCV] Move all isel cases for ISD::ConstantFP into RISCVDAGToDAGISel::Select.
authorCraig Topper <craig.topper@sifive.com>
Sun, 5 Feb 2023 01:31:37 +0000 (17:31 -0800)
committerCraig Topper <craig.topper@sifive.com>
Sun, 5 Feb 2023 01:31:39 +0000 (17:31 -0800)
After D142953, non-zero cases were handled in RISCVDAGToDAGISel::Select
and zeros were handled with isel patterns. The zeros cases are
sufficiently similar to zero that we might as well handle them all
together. We already needed to detect the cases to skip out to
tablegen.

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
llvm/lib/Target/RISCV/RISCVInstrInfoD.td
llvm/lib/Target/RISCV/RISCVInstrInfoF.td
llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td

index 780bc6c..82a3458 100644 (file)
@@ -712,16 +712,16 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
   }
   case ISD::ConstantFP: {
     const APFloat &APF = cast<ConstantFPSDNode>(Node)->getValueAPF();
-    // td can handle +0.0 already.
-    if (APF.isPosZero())
-      break;
-    // Special case: a 64 bit -0.0 uses more instructions than fmv + fneg.
-    if (APF.isNegZero() && VT == MVT::f64)
-      break;
-    assert(VT.bitsLE(Subtarget->getXLenVT()) &&
-           "Cannot create a 64 bit floating-point immediate value for rv32");
-    SDValue Imm = selectImm(CurDAG, DL, XLenVT,
-                            APF.bitcastToAPInt().getSExtValue(), *Subtarget);
+    bool NegZeroF64 = APF.isNegZero() && VT == MVT::f64;
+    SDValue Imm;
+    // For +0.0 or f64 -0.0 we need to start from X0. For all others, we will
+    // create an integer immediate.
+    if (APF.isPosZero() || NegZeroF64)
+      Imm = CurDAG->getRegister(RISCV::X0, XLenVT);
+    else
+      Imm = selectImm(CurDAG, DL, XLenVT, APF.bitcastToAPInt().getSExtValue(),
+                      *Subtarget);
+
     unsigned Opc;
     switch (VT.SimpleTy) {
     default:
@@ -733,10 +733,21 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
       Opc = RISCV::FMV_W_X;
       break;
     case MVT::f64:
-      Opc = RISCV::FMV_D_X;
+      // For RV32, we can't move from a GPR, we need to convert instead. This
+      // should only happen for +0.0 and -0.0.
+      assert((Subtarget->is64Bit() || APF.isZero()) && "Unexpected constant");
+      Opc = Subtarget->is64Bit() ? RISCV::FMV_D_X : RISCV::FCVT_D_W;
       break;
     }
-    ReplaceNode(Node, CurDAG->getMachineNode(Opc, DL, VT, Imm));
+
+    SDNode *Res = CurDAG->getMachineNode(Opc, DL, VT, Imm);
+
+    // For f64 -0.0, we need to insert a fneg.d idiom.
+    if (NegZeroF64)
+      Res = CurDAG->getMachineNode(RISCV::FSGNJN_D, DL, VT, SDValue(Res, 0),
+                                   SDValue(Res, 0));
+
+    ReplaceNode(Node, Res);
     return;
   }
   case ISD::SHL: {
index cd6ff9e..0adb000 100644 (file)
@@ -348,11 +348,6 @@ def SplitF64Pseudo
 
 let Predicates = [HasStdExtD, IsRV32] in {
 
-/// Float constants
-def : Pat<(f64 (fpimm0)), (FCVT_D_W (i32 X0))>;
-def : Pat<(f64 (fpimmneg0)), (FSGNJN_D (FCVT_D_W (i32 X0)),
-                                       (FCVT_D_W (i32 X0)))>;
-
 // double->[u]int. Round-to-zero must be used.
 def : Pat<(i32 (any_fp_to_sint FPR64:$rs1)), (FCVT_W_D FPR64:$rs1, 0b001)>;
 def : Pat<(i32 (any_fp_to_uint FPR64:$rs1)), (FCVT_WU_D FPR64:$rs1, 0b001)>;
@@ -374,11 +369,6 @@ def : Pat<(any_uint_to_fp (i32 GPR:$rs1)), (FCVT_D_WU GPR:$rs1)>;
 
 let Predicates = [HasStdExtD, IsRV64] in {
 
-/// Float constants
-def : Pat<(f64 (fpimm0)), (FMV_D_X (i64 X0))>;
-def : Pat<(f64 (fpimmneg0)), (FSGNJN_D (FMV_D_X (i64 X0)),
-                                       (FMV_D_X (i64 X0)))>;
-
 // Moves (no conversion)
 def : Pat<(bitconvert (i64 GPR:$rs1)), (FMV_D_X GPR:$rs1)>;
 def : Pat<(i64 (bitconvert FPR64:$rs1)), (FMV_X_D FPR64:$rs1)>;
index 966e4cf..a771e29 100644 (file)
@@ -436,7 +436,6 @@ def : InstAlias<"fge.s $rd, $rs, $rt",
 
 /// Floating point constants
 def fpimm0    : PatLeaf<(fpimm), [{ return N->isExactlyValue(+0.0); }]>;
-def fpimmneg0 : PatLeaf<(fpimm), [{ return N->isExactlyValue(-0.0); }]>;
 
 /// Generic pattern classes
 class PatSetCC<RegisterClass Ty, SDPatternOperator OpNode, CondCode Cond, RVInst Inst>
@@ -452,9 +451,6 @@ class PatFprFprDynFrm<SDPatternOperator OpNode, RVInstRFrm Inst,
 
 let Predicates = [HasStdExtF] in {
 
-/// Float constants
-def : Pat<(f32 (fpimm0)), (FMV_W_X X0)>;
-
 /// Float conversion operations
 
 // [u]int32<->float conversion patterns must be gated on IsRV32 or IsRV64, so
index 28c40a6..43e8fa1 100644 (file)
@@ -326,9 +326,6 @@ defm : LdPat<load, FLH, f16>;
 
 defm : StPat<store, FSH, FPR16, f16>;
 
-/// Floating point constant +0.0
-def : Pat<(f16 (fpimm0)), (FMV_H_X X0)>;
-
 /// Float conversion operations
 
 // f32 -> f16, f16 -> f32