Skip to content

Conversation

@ChunyuLiao
Copy link
Member

We use fli+fneg to generate negative float, eliminate the fneg for fma.
Fold fma to vfnmsac.vf,vfnmsub.vf, vfnmacc.vf, vfnmadd.vf

We use fli+fneg to generate negative float.
Perhaps we could eliminate the fneg instruction
@llvmbot
Copy link
Member

llvmbot commented Dec 29, 2025

@llvm/pr-subscribers-backend-risc-v

Author: Liao Chunyu (ChunyuLiao)

Changes

We use fli+fneg to generate negative float, eliminate the fneg for fma.
Fold fma to vfnmsac.vf,vfnmsub.vf, vfnmacc.vf, vfnmadd.vf


Full diff: https://github.com/llvm/llvm-project/pull/173808.diff

2 Files Affected:

  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td (+16)
  • (modified) llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll (+46)
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 1047860ec8db6..6f997082a3d35 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
@@ -33,3 +33,49 @@ 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:    vsetvli a0, zero, e32, m2, ta, ma
+; 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
+}
+
+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:    vsetvli a0, zero, e32, m2, ta, ma
+; 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
+}
+
+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:    vsetvli a0, zero, e32, m4, ta, ma
+; 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)
+  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:    vsetvli a0, zero, e32, m4, ta, ma
+; 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)
+  ret <vscale x 8 x float> %vd
+}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants