[llvm] [RISCV] Add more patten for FMA instruction to eliminate the fneg (PR #173808)
Liao Chunyu via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 30 00:16:44 PST 2025
https://github.com/ChunyuLiao updated https://github.com/llvm/llvm-project/pull/173808
>From 08190d617e228dcb0d4df9ce68072d507210bdcc Mon Sep 17 00:00:00 2001
From: Liao Chunyu <chunyu at iscas.ac.cn>
Date: Fri, 26 Dec 2025 09:35:44 +0000
Subject: [PATCH 1/4] init testcase
---
llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll | 50 ++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll b/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
index 1047860ec8db6..4185094af4340 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
@@ -33,3 +33,53 @@ define <vscale x 8 x double> @vsplat_f64_neg1() {
; CHECK-NEXT: ret
ret <vscale x 8 x double> splat (double -1.0)
}
+
+define <vscale x 4 x float> @vfnmsac(<vscale x 4 x float> %va, <vscale x 4 x float> %vb) {
+; CHECK-LABEL: vfnmsac:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.s fa5, 2.0
+; CHECK-NEXT: fneg.s fa5, fa5
+; CHECK-NEXT: vsetvli a0, zero, e32, m2, ta, ma
+; CHECK-NEXT: vfmacc.vf v8, fa5, v10
+; CHECK-NEXT: ret
+ %vd = tail call <vscale x 4 x float> @llvm.fmuladd.nxv4f32(<vscale x 4 x float> %vb, <vscale x 4 x float> splat (float -2.000000e+00), <vscale x 4 x float> %va)
+ ret <vscale x 4 x float> %vd
+}
+
+define <vscale x 4 x float> @vfnmsub(<vscale x 4 x float> %va, <vscale x 4 x float> %vb) {
+; CHECK-LABEL: vfnmsub:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.s fa5, 2.0
+; CHECK-NEXT: fneg.s fa5, fa5
+; CHECK-NEXT: vsetvli a0, zero, e32, m2, ta, ma
+; CHECK-NEXT: vfmadd.vf v8, fa5, v10
+; CHECK-NEXT: ret
+ %vd = tail call <vscale x 4 x float> @llvm.fmuladd.nxv4f32(<vscale x 4 x float> splat (float -2.000000e+00), <vscale x 4 x float> %va, <vscale x 4 x float> %vb)
+ ret <vscale x 4 x float> %vd
+}
+
+define <vscale x 8 x float> @vfnmacc(<vscale x 8 x float> %va, <vscale x 8 x float> %vb) {
+; CHECK-LABEL: vfnmacc:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.s fa5, 2.0
+; CHECK-NEXT: fneg.s fa5, fa5
+; CHECK-NEXT: vsetvli a0, zero, e32, m4, ta, ma
+; CHECK-NEXT: vfmsac.vf v8, fa5, v12
+; CHECK-NEXT: ret
+ %neg = fneg <vscale x 8 x float> %va
+ %vd = call <vscale x 8 x float> @llvm.fma.v8f32(<vscale x 8 x float> %vb, <vscale x 8 x float> splat (float -2.000000e+00), <vscale x 8 x float> %neg)
+ ret <vscale x 8 x float> %vd
+}
+
+define <vscale x 8 x float> @vfnmadd(<vscale x 8 x float> %va, <vscale x 8 x float> %vb) {
+; CHECK-LABEL: vfnmadd:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.s fa5, 2.0
+; CHECK-NEXT: fneg.s fa5, fa5
+; CHECK-NEXT: vsetvli a0, zero, e32, m4, ta, ma
+; CHECK-NEXT: vfmsub.vf v8, fa5, v12
+; CHECK-NEXT: ret
+ %neg = fneg <vscale x 8 x float> %vb
+ %vd = call <vscale x 8 x float> @llvm.fma.v8f32(<vscale x 8 x float> %va, <vscale x 8 x float> splat (float -2.000000e+00), <vscale x 8 x float> %neg)
+ ret <vscale x 8 x float> %vd
+}
>From bd73cfe1e9fe32cf7b12412fb209c9278a6ce91e Mon Sep 17 00:00:00 2001
From: Liao Chunyu <chunyu at iscas.ac.cn>
Date: Fri, 26 Dec 2025 09:50:21 +0000
Subject: [PATCH 2/4] [RISCV] Add more patten for FMA instruction to eliminate
the fneg We use fli+fneg to generate negative float. Perhaps we could
eliminate the fneg instruction
---
.../Target/RISCV/RISCVInstrInfoVSDPatterns.td | 16 ++++++++++++++++
llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll | 12 ++++--------
2 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td
index b3cc33d31761d..552432c4b156a 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td
@@ -1326,6 +1326,22 @@ foreach fvti = AllFloatVectors in {
// RISCVInsertReadWriteCSR
FRM_DYN,
fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>;
+ def : Pat<(fvti.Vector (any_fma (SplatFPOp (fneg fvti.ScalarRegClass:$rs1)),
+ fvti.RegClass:$rd, (fneg fvti.RegClass:$rs2))),
+ (!cast<Instruction>("PseudoVFNMADD_V" # fvti.ScalarSuffix # "_" # suffix)
+ fvti.RegClass:$rd, fvti.ScalarRegClass:$rs1, fvti.RegClass:$rs2,
+ // Value to indicate no rounding mode change in
+ // RISCVInsertReadWriteCSR
+ FRM_DYN,
+ fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>;
+ def : Pat<(fvti.Vector (any_fma (SplatFPOp (fneg fvti.ScalarRegClass:$rs1)),
+ fvti.RegClass:$rd, fvti.RegClass:$rs2)),
+ (!cast<Instruction>("PseudoVFNMSUB_V" # fvti.ScalarSuffix # "_" # suffix)
+ fvti.RegClass:$rd, fvti.ScalarRegClass:$rs1, fvti.RegClass:$rs2,
+ // Value to indicate no rounding mode change in
+ // RISCVInsertReadWriteCSR
+ FRM_DYN,
+ fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>;
}
}
diff --git a/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll b/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
index 4185094af4340..6f997082a3d35 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
@@ -38,9 +38,8 @@ define <vscale x 4 x float> @vfnmsac(<vscale x 4 x float> %va, <vscale x 4 x flo
; CHECK-LABEL: vfnmsac:
; CHECK: # %bb.0:
; CHECK-NEXT: fli.s fa5, 2.0
-; CHECK-NEXT: fneg.s fa5, fa5
; CHECK-NEXT: vsetvli a0, zero, e32, m2, ta, ma
-; CHECK-NEXT: vfmacc.vf v8, fa5, v10
+; CHECK-NEXT: vfnmsac.vf v8, fa5, v10
; CHECK-NEXT: ret
%vd = tail call <vscale x 4 x float> @llvm.fmuladd.nxv4f32(<vscale x 4 x float> %vb, <vscale x 4 x float> splat (float -2.000000e+00), <vscale x 4 x float> %va)
ret <vscale x 4 x float> %vd
@@ -50,9 +49,8 @@ define <vscale x 4 x float> @vfnmsub(<vscale x 4 x float> %va, <vscale x 4 x flo
; CHECK-LABEL: vfnmsub:
; CHECK: # %bb.0:
; CHECK-NEXT: fli.s fa5, 2.0
-; CHECK-NEXT: fneg.s fa5, fa5
; CHECK-NEXT: vsetvli a0, zero, e32, m2, ta, ma
-; CHECK-NEXT: vfmadd.vf v8, fa5, v10
+; CHECK-NEXT: vfnmsub.vf v8, fa5, v10
; CHECK-NEXT: ret
%vd = tail call <vscale x 4 x float> @llvm.fmuladd.nxv4f32(<vscale x 4 x float> splat (float -2.000000e+00), <vscale x 4 x float> %va, <vscale x 4 x float> %vb)
ret <vscale x 4 x float> %vd
@@ -62,9 +60,8 @@ define <vscale x 8 x float> @vfnmacc(<vscale x 8 x float> %va, <vscale x 8 x flo
; CHECK-LABEL: vfnmacc:
; CHECK: # %bb.0:
; CHECK-NEXT: fli.s fa5, 2.0
-; CHECK-NEXT: fneg.s fa5, fa5
; CHECK-NEXT: vsetvli a0, zero, e32, m4, ta, ma
-; CHECK-NEXT: vfmsac.vf v8, fa5, v12
+; CHECK-NEXT: vfnmacc.vf v8, fa5, v12
; CHECK-NEXT: ret
%neg = fneg <vscale x 8 x float> %va
%vd = call <vscale x 8 x float> @llvm.fma.v8f32(<vscale x 8 x float> %vb, <vscale x 8 x float> splat (float -2.000000e+00), <vscale x 8 x float> %neg)
@@ -75,9 +72,8 @@ define <vscale x 8 x float> @vfnmadd(<vscale x 8 x float> %va, <vscale x 8 x flo
; CHECK-LABEL: vfnmadd:
; CHECK: # %bb.0:
; CHECK-NEXT: fli.s fa5, 2.0
-; CHECK-NEXT: fneg.s fa5, fa5
; CHECK-NEXT: vsetvli a0, zero, e32, m4, ta, ma
-; CHECK-NEXT: vfmsub.vf v8, fa5, v12
+; CHECK-NEXT: vfnmadd.vf v8, fa5, v12
; CHECK-NEXT: ret
%neg = fneg <vscale x 8 x float> %vb
%vd = call <vscale x 8 x float> @llvm.fma.v8f32(<vscale x 8 x float> %va, <vscale x 8 x float> splat (float -2.000000e+00), <vscale x 8 x float> %neg)
>From 1dcbf4b0f342b710bebb02925cf2559f45624601 Mon Sep 17 00:00:00 2001
From: Liao Chunyu <chunyu at iscas.ac.cn>
Date: Tue, 30 Dec 2025 06:28:37 +0000
Subject: [PATCH 3/4] Revert "[RISCV] Add more patten for FMA instruction to
eliminate the fneg"
This reverts commit bd73cfe1e9fe32cf7b12412fb209c9278a6ce91e.
---
.../Target/RISCV/RISCVInstrInfoVSDPatterns.td | 16 ----------------
llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll | 12 ++++++++----
2 files changed, 8 insertions(+), 20 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td
index 552432c4b156a..b3cc33d31761d 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td
@@ -1326,22 +1326,6 @@ foreach fvti = AllFloatVectors in {
// RISCVInsertReadWriteCSR
FRM_DYN,
fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>;
- def : Pat<(fvti.Vector (any_fma (SplatFPOp (fneg fvti.ScalarRegClass:$rs1)),
- fvti.RegClass:$rd, (fneg fvti.RegClass:$rs2))),
- (!cast<Instruction>("PseudoVFNMADD_V" # fvti.ScalarSuffix # "_" # suffix)
- fvti.RegClass:$rd, fvti.ScalarRegClass:$rs1, fvti.RegClass:$rs2,
- // Value to indicate no rounding mode change in
- // RISCVInsertReadWriteCSR
- FRM_DYN,
- fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>;
- def : Pat<(fvti.Vector (any_fma (SplatFPOp (fneg fvti.ScalarRegClass:$rs1)),
- fvti.RegClass:$rd, fvti.RegClass:$rs2)),
- (!cast<Instruction>("PseudoVFNMSUB_V" # fvti.ScalarSuffix # "_" # suffix)
- fvti.RegClass:$rd, fvti.ScalarRegClass:$rs1, fvti.RegClass:$rs2,
- // Value to indicate no rounding mode change in
- // RISCVInsertReadWriteCSR
- FRM_DYN,
- fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>;
}
}
diff --git a/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll b/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
index 6f997082a3d35..4185094af4340 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
@@ -38,8 +38,9 @@ define <vscale x 4 x float> @vfnmsac(<vscale x 4 x float> %va, <vscale x 4 x flo
; CHECK-LABEL: vfnmsac:
; CHECK: # %bb.0:
; CHECK-NEXT: fli.s fa5, 2.0
+; CHECK-NEXT: fneg.s fa5, fa5
; CHECK-NEXT: vsetvli a0, zero, e32, m2, ta, ma
-; CHECK-NEXT: vfnmsac.vf v8, fa5, v10
+; CHECK-NEXT: vfmacc.vf v8, fa5, v10
; CHECK-NEXT: ret
%vd = tail call <vscale x 4 x float> @llvm.fmuladd.nxv4f32(<vscale x 4 x float> %vb, <vscale x 4 x float> splat (float -2.000000e+00), <vscale x 4 x float> %va)
ret <vscale x 4 x float> %vd
@@ -49,8 +50,9 @@ define <vscale x 4 x float> @vfnmsub(<vscale x 4 x float> %va, <vscale x 4 x flo
; CHECK-LABEL: vfnmsub:
; CHECK: # %bb.0:
; CHECK-NEXT: fli.s fa5, 2.0
+; CHECK-NEXT: fneg.s fa5, fa5
; CHECK-NEXT: vsetvli a0, zero, e32, m2, ta, ma
-; CHECK-NEXT: vfnmsub.vf v8, fa5, v10
+; CHECK-NEXT: vfmadd.vf v8, fa5, v10
; CHECK-NEXT: ret
%vd = tail call <vscale x 4 x float> @llvm.fmuladd.nxv4f32(<vscale x 4 x float> splat (float -2.000000e+00), <vscale x 4 x float> %va, <vscale x 4 x float> %vb)
ret <vscale x 4 x float> %vd
@@ -60,8 +62,9 @@ define <vscale x 8 x float> @vfnmacc(<vscale x 8 x float> %va, <vscale x 8 x flo
; CHECK-LABEL: vfnmacc:
; CHECK: # %bb.0:
; CHECK-NEXT: fli.s fa5, 2.0
+; CHECK-NEXT: fneg.s fa5, fa5
; CHECK-NEXT: vsetvli a0, zero, e32, m4, ta, ma
-; CHECK-NEXT: vfnmacc.vf v8, fa5, v12
+; CHECK-NEXT: vfmsac.vf v8, fa5, v12
; CHECK-NEXT: ret
%neg = fneg <vscale x 8 x float> %va
%vd = call <vscale x 8 x float> @llvm.fma.v8f32(<vscale x 8 x float> %vb, <vscale x 8 x float> splat (float -2.000000e+00), <vscale x 8 x float> %neg)
@@ -72,8 +75,9 @@ define <vscale x 8 x float> @vfnmadd(<vscale x 8 x float> %va, <vscale x 8 x flo
; CHECK-LABEL: vfnmadd:
; CHECK: # %bb.0:
; CHECK-NEXT: fli.s fa5, 2.0
+; CHECK-NEXT: fneg.s fa5, fa5
; CHECK-NEXT: vsetvli a0, zero, e32, m4, ta, ma
-; CHECK-NEXT: vfnmadd.vf v8, fa5, v12
+; CHECK-NEXT: vfmsub.vf v8, fa5, v12
; CHECK-NEXT: ret
%neg = fneg <vscale x 8 x float> %vb
%vd = call <vscale x 8 x float> @llvm.fma.v8f32(<vscale x 8 x float> %va, <vscale x 8 x float> splat (float -2.000000e+00), <vscale x 8 x float> %neg)
>From c74034ea060b371974f3911a5b9b16600155cbf9 Mon Sep 17 00:00:00 2001
From: Liao Chunyu <chunyu at iscas.ac.cn>
Date: Tue, 30 Dec 2025 07:50:58 +0000
Subject: [PATCH 4/4] [RISCV] (fma (splat (fneg X)), Y, Z) -> (fma (fneg (splat
X)), Y, Z)
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 18 +++++++++++++++++-
llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll | 12 ++++--------
2 files changed, 21 insertions(+), 9 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 04ff1a978a131..e591a9a2b6896 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -1818,7 +1818,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
ISD::MUL, ISD::SDIV, ISD::UDIV,
ISD::SREM, ISD::UREM, ISD::INSERT_VECTOR_ELT,
ISD::ABS, ISD::CTPOP, ISD::VECTOR_SHUFFLE,
- ISD::VSELECT, ISD::VECREDUCE_ADD});
+ ISD::FMA, ISD::VSELECT, ISD::VECREDUCE_ADD});
if (Subtarget.hasVendorXTHeadMemPair())
setTargetDAGCombine({ISD::LOAD, ISD::STORE});
@@ -21034,6 +21034,22 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
return V;
return SDValue();
}
+ case ISD::FMA: {
+ SDValue N0 = N->getOperand(0);
+ SDValue N1 = N->getOperand(1);
+ if (N0.getOpcode() != ISD::SPLAT_VECTOR)
+ std::swap(N0, N1);
+ if (N0->getOpcode() != ISD::SPLAT_VECTOR)
+ return SDValue();
+ SDValue SplatN0 = N0->getOperand(0);
+ if (SplatN0.getOpcode() != ISD::FNEG || !SplatN0.hasOneUse())
+ return SDValue();
+ EVT VT = N->getValueType(0);
+ SDValue Splat =
+ DAG.getNode(ISD::SPLAT_VECTOR, DL, VT, SplatN0->getOperand(0));
+ SDValue Fneg = DAG.getNode(ISD::FNEG, DL, VT, Splat);
+ return DAG.getNode(ISD::FMA, DL, VT, Fneg, N1, N->getOperand(2));
+ }
case ISD::SETCC:
return performSETCCCombine(N, DCI, Subtarget);
case ISD::SIGN_EXTEND_INREG:
diff --git a/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll b/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
index 4185094af4340..6f997082a3d35 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
@@ -38,9 +38,8 @@ define <vscale x 4 x float> @vfnmsac(<vscale x 4 x float> %va, <vscale x 4 x flo
; CHECK-LABEL: vfnmsac:
; CHECK: # %bb.0:
; CHECK-NEXT: fli.s fa5, 2.0
-; CHECK-NEXT: fneg.s fa5, fa5
; CHECK-NEXT: vsetvli a0, zero, e32, m2, ta, ma
-; CHECK-NEXT: vfmacc.vf v8, fa5, v10
+; CHECK-NEXT: vfnmsac.vf v8, fa5, v10
; CHECK-NEXT: ret
%vd = tail call <vscale x 4 x float> @llvm.fmuladd.nxv4f32(<vscale x 4 x float> %vb, <vscale x 4 x float> splat (float -2.000000e+00), <vscale x 4 x float> %va)
ret <vscale x 4 x float> %vd
@@ -50,9 +49,8 @@ define <vscale x 4 x float> @vfnmsub(<vscale x 4 x float> %va, <vscale x 4 x flo
; CHECK-LABEL: vfnmsub:
; CHECK: # %bb.0:
; CHECK-NEXT: fli.s fa5, 2.0
-; CHECK-NEXT: fneg.s fa5, fa5
; CHECK-NEXT: vsetvli a0, zero, e32, m2, ta, ma
-; CHECK-NEXT: vfmadd.vf v8, fa5, v10
+; CHECK-NEXT: vfnmsub.vf v8, fa5, v10
; CHECK-NEXT: ret
%vd = tail call <vscale x 4 x float> @llvm.fmuladd.nxv4f32(<vscale x 4 x float> splat (float -2.000000e+00), <vscale x 4 x float> %va, <vscale x 4 x float> %vb)
ret <vscale x 4 x float> %vd
@@ -62,9 +60,8 @@ define <vscale x 8 x float> @vfnmacc(<vscale x 8 x float> %va, <vscale x 8 x flo
; CHECK-LABEL: vfnmacc:
; CHECK: # %bb.0:
; CHECK-NEXT: fli.s fa5, 2.0
-; CHECK-NEXT: fneg.s fa5, fa5
; CHECK-NEXT: vsetvli a0, zero, e32, m4, ta, ma
-; CHECK-NEXT: vfmsac.vf v8, fa5, v12
+; CHECK-NEXT: vfnmacc.vf v8, fa5, v12
; CHECK-NEXT: ret
%neg = fneg <vscale x 8 x float> %va
%vd = call <vscale x 8 x float> @llvm.fma.v8f32(<vscale x 8 x float> %vb, <vscale x 8 x float> splat (float -2.000000e+00), <vscale x 8 x float> %neg)
@@ -75,9 +72,8 @@ define <vscale x 8 x float> @vfnmadd(<vscale x 8 x float> %va, <vscale x 8 x flo
; CHECK-LABEL: vfnmadd:
; CHECK: # %bb.0:
; CHECK-NEXT: fli.s fa5, 2.0
-; CHECK-NEXT: fneg.s fa5, fa5
; CHECK-NEXT: vsetvli a0, zero, e32, m4, ta, ma
-; CHECK-NEXT: vfmsub.vf v8, fa5, v12
+; CHECK-NEXT: vfnmadd.vf v8, fa5, v12
; CHECK-NEXT: ret
%neg = fneg <vscale x 8 x float> %vb
%vd = call <vscale x 8 x float> @llvm.fma.v8f32(<vscale x 8 x float> %va, <vscale x 8 x float> splat (float -2.000000e+00), <vscale x 8 x float> %neg)
More information about the llvm-commits
mailing list