[llvm] [DAGCombine]Fold (fadd A, Splat(fneg(B))) -> (fsub A, Splat(B)) (PR #173967)

Liao Chunyu via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 30 00:31:28 PST 2025


https://github.com/ChunyuLiao created https://github.com/llvm/llvm-project/pull/173967

There are optimizations for RISCV, and no regressions have been observed on other architectures.

>From 51a0325b1cb8d2b9e08d679b33037887ab656f47 Mon Sep 17 00:00:00 2001
From: Liao Chunyu <chunyu at iscas.ac.cn>
Date: Tue, 30 Dec 2025 06:20:40 +0000
Subject: [PATCH 1/2] init testcase

---
 llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll b/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
index 1047860ec8db6..f595c17dd51f8 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
@@ -33,3 +33,15 @@ 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 8 x float> @vfsub_vf_nxv8f32(<vscale x 8 x float> %va) {
+; CHECK-LABEL: vfsub_vf_nxv8f32:
+; 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:    vfadd.vf v8, v8, fa5
+; CHECK-NEXT:    ret
+  %vd = fadd <vscale x 8 x float> %va, splat (float -2.000000e+00)
+  ret <vscale x 8 x float> %vd
+}

>From 53feacfeb2b638ce1a60bde313a52b8cadc4a283 Mon Sep 17 00:00:00 2001
From: Liao Chunyu <chunyu at iscas.ac.cn>
Date: Tue, 30 Dec 2025 06:21:48 +0000
Subject: [PATCH 2/2] [DAGCombine]Fold (fadd A, Splat(fneg(B))) -> (fsub A,
 Splat(B))

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 13 +++++++++++++
 llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll    |  3 +--
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 74d00317c3649..32348ad1dfc91 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -17965,6 +17965,19 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
             N0, DAG, LegalOperations, ForCodeSize))
       return DAG.getNode(ISD::FSUB, DL, VT, N1, NegN0);
 
+  // fold (fadd A, Splat(fneg(B))) -> (fsub A, Splat(B))
+  if (VT.isVector() &&
+      (!LegalOperations || TLI.isOperationLegalOrCustom(ISD::FSUB, VT))) {
+    if (N1.getOpcode() == ISD::SPLAT_VECTOR) {
+      SDValue SplatN0 = N1->getOperand(0);
+      if (SplatN0.getOpcode() == ISD::FNEG && SplatN0.hasOneUse()) {
+        SDValue Splat =
+            DAG.getNode(ISD::SPLAT_VECTOR, DL, VT, SplatN0->getOperand(0));
+        return DAG.getNode(ISD::FSUB, DL, VT, N0, Splat);
+      }
+    }
+  }
+
   auto isFMulNegTwo = [](SDValue FMul) {
     if (!FMul.hasOneUse() || FMul.getOpcode() != ISD::FMUL)
       return false;
diff --git a/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll b/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
index f595c17dd51f8..8c6cb6bd59c54 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 8 x float> @vfsub_vf_nxv8f32(<vscale x 8 x float> %va) {
 ; CHECK-LABEL: vfsub_vf_nxv8f32:
 ; 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:    vfadd.vf v8, v8, fa5
+; CHECK-NEXT:    vfsub.vf v8, v8, fa5
 ; CHECK-NEXT:    ret
   %vd = fadd <vscale x 8 x float> %va, splat (float -2.000000e+00)
   ret <vscale x 8 x float> %vd



More information about the llvm-commits mailing list