[llvm] [RISCV] Move the rest of Zfa FLI instruction handling to lowerConstantFP. (PR #109217)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 19 14:26:16 PDT 2024


https://github.com/topperc updated https://github.com/llvm/llvm-project/pull/109217

>From 94239b8b8da1d87bd66e0af5140d081d2325b241 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Wed, 18 Sep 2024 16:02:13 -0700
Subject: [PATCH 1/3] [RISCV] Move the rest of Zfa FLI instruction handling to
 lowerConstantFP.

We already moved the fneg case. This moves the rest so we can
drop the custom isel.
---
 llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 30 ---------------------
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 24 ++++++++++-------
 2 files changed, 14 insertions(+), 40 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index f22ab1e5e9d48a..fcd46b5921c4de 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -889,29 +889,6 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
   }
   case ISD::ConstantFP: {
     const APFloat &APF = cast<ConstantFPSDNode>(Node)->getValueAPF();
-    int FPImm = static_cast<const RISCVTargetLowering *>(TLI)->getLegalZfaFPImm(
-        APF, VT);
-    if (FPImm >= 0) {
-      unsigned Opc;
-      switch (VT.SimpleTy) {
-      default:
-        llvm_unreachable("Unexpected size");
-      case MVT::f16:
-        Opc = RISCV::FLI_H;
-        break;
-      case MVT::f32:
-        Opc = RISCV::FLI_S;
-        break;
-      case MVT::f64:
-        Opc = RISCV::FLI_D;
-        break;
-      }
-      SDNode *Res = CurDAG->getMachineNode(
-          Opc, DL, VT, CurDAG->getTargetConstant(FPImm, DL, XLenVT));
-
-      ReplaceNode(Node, Res);
-      return;
-    }
 
     bool NegZeroF64 = APF.isNegZero() && VT == MVT::f64;
     SDValue Imm;
@@ -3552,13 +3529,6 @@ bool RISCVDAGToDAGISel::selectScalarFPAsInt(SDValue N, SDValue &Imm) {
 
   MVT VT = CFP->getSimpleValueType(0);
 
-  // Even if this FPImm requires an additional FNEG (i.e. the second element of
-  // the returned pair is true) we still prefer FLI + FNEG over immediate
-  // materialization as the latter might generate a longer instruction sequence.
-  if (static_cast<const RISCVTargetLowering *>(TLI)->getLegalZfaFPImm(APF,
-                                                                      VT) >= 0)
-    return false;
-
   MVT XLenVT = Subtarget->getXLenVT();
   if (VT == MVT::f64 && !Subtarget->is64Bit()) {
     assert(APF.isNegZero() && "Unexpected constant.");
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 189fb741f34cd1..fc12c88445200d 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -2268,9 +2268,6 @@ bool RISCVTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
   if (!IsLegalVT)
     return false;
 
-  if (getLegalZfaFPImm(Imm, VT) >= 0)
-    return true;
-
   // Cannot create a 64 bit floating-point immediate value for rv32.
   if (Subtarget.getXLen() < VT.getScalarSizeInBits()) {
     // td can handle +0.0 or -0.0 already.
@@ -5802,22 +5799,29 @@ SDValue RISCVTargetLowering::lowerConstantFP(SDValue Op,
   MVT VT = Op.getSimpleValueType();
   const APFloat &Imm = cast<ConstantFPSDNode>(Op)->getValueAPF();
 
-  if (getLegalZfaFPImm(Imm, VT) >= 0)
-    return Op;
+  // Can this constant be select by a Zfa FLI instruction?
+  bool Negate = false;
+  int Index = getLegalZfaFPImm(Imm, VT);
 
-  if (!Imm.isNegative())
-    return SDValue();
+  // If the constant is negative, try negating.
+  if (Index < 0 && Imm.isNegative()) {
+    Index = getLegalZfaFPImm(-Imm, VT);
+    Negate = true;
+  }
 
-  int Index = getLegalZfaFPImm(-Imm, VT);
+  // If we couldn't find a FLI lowering, fall back to generic code.
   if (Index < 0)
     return SDValue();
 
   // Emit an FLI+FNEG. We use a custom node to hide from constant folding.
   SDLoc DL(Op);
   SDValue Const =
-      DAG.getNode(RISCVISD::FLI, Op, VT,
+      DAG.getNode(RISCVISD::FLI, DL, VT,
                   DAG.getTargetConstant(Index, DL, Subtarget.getXLenVT()));
-  return DAG.getNode(ISD::FNEG, Op, VT, Const);
+  if (!Negate)
+    return Const;
+
+  return DAG.getNode(ISD::FNEG, DL, VT, Const);
 }
 
 static SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG,

>From 0fa3db14e039a58d2d3ddbc2e0ec58f3b4ca335d Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Wed, 18 Sep 2024 22:04:31 -0700
Subject: [PATCH 2/3] fixup! Add getLegalZfaFPImm back to isFPImmLegal.

---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp |  3 +++
 llvm/test/CodeGen/RISCV/double-zfa.ll       | 28 +++++++++++++++++++
 llvm/test/CodeGen/RISCV/float-zfa.ll        | 17 ++++++++++++
 llvm/test/CodeGen/RISCV/half-zfa.ll         | 30 +++++++++++++++++++++
 4 files changed, 78 insertions(+)

diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index fc12c88445200d..7b183a684011c3 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -2268,6 +2268,9 @@ bool RISCVTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
   if (!IsLegalVT)
     return false;
 
+  if (getLegalZfaFPImm(Imm, VT) >= 0)
+    return true;
+
   // Cannot create a 64 bit floating-point immediate value for rv32.
   if (Subtarget.getXLen() < VT.getScalarSizeInBits()) {
     // td can handle +0.0 or -0.0 already.
diff --git a/llvm/test/CodeGen/RISCV/double-zfa.ll b/llvm/test/CodeGen/RISCV/double-zfa.ll
index 24d62f08e069d2..f8c10e19439475 100644
--- a/llvm/test/CodeGen/RISCV/double-zfa.ll
+++ b/llvm/test/CodeGen/RISCV/double-zfa.ll
@@ -371,3 +371,31 @@ define double @fma_neg_addend_multiplicand(double %x) nounwind {
   %a = call double @llvm.fma.f32(double %x, double -0.5, double -0.25)
   ret double %a
 }
+
+define double @select_loadfpimm(double %x) nounwind {
+; RV32IDZFA-LABEL: select_loadfpimm:
+; RV32IDZFA:       # %bb.0: # %entry
+; RV32IDZFA-NEXT:    fcvt.d.w fa5, zero
+; RV32IDZFA-NEXT:    fle.d a0, fa5, fa0
+; RV32IDZFA-NEXT:    fli.d fa0, 0.5
+; RV32IDZFA-NEXT:    bnez a0, .LBB35_2
+; RV32IDZFA-NEXT:  # %bb.1:
+; RV32IDZFA-NEXT:    fneg.d fa0, fa0
+; RV32IDZFA-NEXT:  .LBB35_2: # %entry
+; RV32IDZFA-NEXT:    ret
+;
+; RV64DZFA-LABEL: select_loadfpimm:
+; RV64DZFA:       # %bb.0: # %entry
+; RV64DZFA-NEXT:    fmv.d.x fa5, zero
+; RV64DZFA-NEXT:    fle.d a0, fa5, fa0
+; RV64DZFA-NEXT:    fli.d fa0, 0.5
+; RV64DZFA-NEXT:    bnez a0, .LBB35_2
+; RV64DZFA-NEXT:  # %bb.1:
+; RV64DZFA-NEXT:    fneg.d fa0, fa0
+; RV64DZFA-NEXT:  .LBB35_2: # %entry
+; RV64DZFA-NEXT:    ret
+entry:
+  %cmp = fcmp ult double %x, 0.000000e+00
+  %sel = select i1 %cmp, double -5.000000e-01, double 5.000000e-01
+  ret double %sel
+}
diff --git a/llvm/test/CodeGen/RISCV/float-zfa.ll b/llvm/test/CodeGen/RISCV/float-zfa.ll
index aab045bcb29816..5f0f45eed98ff8 100644
--- a/llvm/test/CodeGen/RISCV/float-zfa.ll
+++ b/llvm/test/CodeGen/RISCV/float-zfa.ll
@@ -310,3 +310,20 @@ define float @fma_neg_addend_multiplicand(float %x) nounwind {
   %a = call float @llvm.fma.f32(float %x, float -0.5, float -0.25)
   ret float %a
 }
+
+define float @select_loadfpimm(float %x) nounwind {
+; CHECK-LABEL: select_loadfpimm:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    fmv.w.x fa5, zero
+; CHECK-NEXT:    fle.s a0, fa5, fa0
+; CHECK-NEXT:    fli.s fa0, 0.5
+; CHECK-NEXT:    bnez a0, .LBB30_2
+; CHECK-NEXT:  # %bb.1:
+; CHECK-NEXT:    fneg.s fa0, fa0
+; CHECK-NEXT:  .LBB30_2: # %entry
+; CHECK-NEXT:    ret
+entry:
+  %cmp = fcmp ult float %x, 0.000000e+00
+  %sel = select i1 %cmp, float -5.000000e-01, float 5.000000e-01
+  ret float %sel
+}
diff --git a/llvm/test/CodeGen/RISCV/half-zfa.ll b/llvm/test/CodeGen/RISCV/half-zfa.ll
index fe0badd46f420a..54ec90b8eab3eb 100644
--- a/llvm/test/CodeGen/RISCV/half-zfa.ll
+++ b/llvm/test/CodeGen/RISCV/half-zfa.ll
@@ -314,3 +314,33 @@ define half @fma_neg_addend_multiplicand(half %x) nounwind {
   %a = call half @llvm.fma.f32(half %x, half -0.5, half -0.25)
   ret half %a
 }
+
+define half @select_loadfpimm(half %x) nounwind {
+; CHECK-LABEL: select_loadfpimm:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    fmv.h.x fa5, zero
+; CHECK-NEXT:    fle.h a0, fa5, fa0
+; CHECK-NEXT:    fli.h fa0, 0.5
+; CHECK-NEXT:    bnez a0, .LBB16_2
+; CHECK-NEXT:  # %bb.1:
+; CHECK-NEXT:    fneg.h fa0, fa0
+; CHECK-NEXT:  .LBB16_2: # %entry
+; CHECK-NEXT:    ret
+;
+; ZFHMIN-LABEL: select_loadfpimm:
+; ZFHMIN:       # %bb.0: # %entry
+; ZFHMIN-NEXT:    fcvt.s.h fa5, fa0
+; ZFHMIN-NEXT:    fmv.w.x fa4, zero
+; ZFHMIN-NEXT:    fle.s a0, fa4, fa5
+; ZFHMIN-NEXT:    xori a0, a0, 1
+; ZFHMIN-NEXT:    slli a0, a0, 1
+; ZFHMIN-NEXT:    lui a1, %hi(.LCPI16_0)
+; ZFHMIN-NEXT:    addi a1, a1, %lo(.LCPI16_0)
+; ZFHMIN-NEXT:    add a0, a1, a0
+; ZFHMIN-NEXT:    flh fa0, 0(a0)
+; ZFHMIN-NEXT:    ret
+entry:
+  %cmp = fcmp ult half %x, 0.000000e+00
+  %sel = select i1 %cmp, half -5.000000e-01, half 5.000000e-01
+  ret half %sel
+}

>From 204a0226fa93b12ec1e54b4465bb27c41a021d55 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Thu, 19 Sep 2024 14:25:54 -0700
Subject: [PATCH 3/3] fixup! fix comment

---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 7b183a684011c3..c4458b14f36ece 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -5802,7 +5802,7 @@ SDValue RISCVTargetLowering::lowerConstantFP(SDValue Op,
   MVT VT = Op.getSimpleValueType();
   const APFloat &Imm = cast<ConstantFPSDNode>(Op)->getValueAPF();
 
-  // Can this constant be select by a Zfa FLI instruction?
+  // Can this constant be selected by a Zfa FLI instruction?
   bool Negate = false;
   int Index = getLegalZfaFPImm(Imm, VT);
 



More information about the llvm-commits mailing list