[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
Wed Sep 18 22:04:49 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/2] [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/2] 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
+}
More information about the llvm-commits
mailing list