[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
Wed Jan 7 18:50:34 PST 2026
https://github.com/ChunyuLiao updated https://github.com/llvm/llvm-project/pull/173967
>From fc39d23acac3d0458545af8530b6678b41e4d775 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 01/11] 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 6f997082a3d35..532d165791fa0 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
@@ -79,3 +79,15 @@ define <vscale x 8 x float> @vfnmadd(<vscale x 8 x float> %va, <vscale x 8 x flo
%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
}
+
+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 5162f9fef26705d2a111f9b1465b7787b17e6653 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 02/11] [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 ee28260a74127..93044e17438ee 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -18038,6 +18038,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 532d165791fa0..e7eac891674e8 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
@@ -84,9 +84,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
>From 596bdccc0ba30601584f8a678cade8d2c63b7bae Mon Sep 17 00:00:00 2001
From: Liao Chunyu <chunyu at iscas.ac.cn>
Date: Wed, 31 Dec 2025 08:53:20 +0000
Subject: [PATCH 03/11] Revert "[DAGCombine]Fold (fadd A, Splat(fneg(B))) ->
(fsub A, Splat(B))"
This reverts commit 53feacfeb2b638ce1a60bde313a52b8cadc4a283.
---
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 13 -------------
llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll | 3 ++-
2 files changed, 2 insertions(+), 14 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 93044e17438ee..ee28260a74127 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -18038,19 +18038,6 @@ 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 e7eac891674e8..532d165791fa0 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
@@ -84,8 +84,9 @@ 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: vfsub.vf v8, v8, fa5
+; 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 53613566151aca5b0d422e16389260075739b872 Mon Sep 17 00:00:00 2001
From: Liao Chunyu <chunyu at iscas.ac.cn>
Date: Wed, 31 Dec 2025 09:49:57 +0000
Subject: [PATCH 04/11] [DAG]Add splat_vector to
TargetLowering::getNegatedExpression splat_vector(fneg(x)) to
splat_vector(x), then DAGCombine performs some optimizations using these
results.
---
llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | 13 +++++++++++++
llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll | 14 ++++++++++++--
2 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 94464e792c645..8e2aa3180fba5 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -7554,6 +7554,19 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
Cost = NegatibleCost::Neutral;
return CFP;
}
+ case ISD::SPLAT_VECTOR: {
+ SDValue X = Op.getOperand(0);
+ if (!isOperationLegal(ISD::SPLAT_VECTOR, VT))
+ break;
+
+ NegatibleCost CostX = NegatibleCost::Expensive;
+ SDValue NegX =
+ getNegatedExpression(X, DAG, LegalOps, OptForSize, CostX, Depth);
+ if (!NegX || CostX >= NegatibleCost::Neutral)
+ break;
+ Cost = CostX;
+ return DAG.getNode(ISD::SPLAT_VECTOR, DL, VT, NegX);
+ }
case ISD::BUILD_VECTOR: {
// Only permit BUILD_VECTOR of constants.
if (llvm::any_of(Op->op_values(), [&](SDValue N) {
diff --git a/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll b/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
index 532d165791fa0..bc91d620d0814 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
@@ -84,10 +84,20 @@ 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
}
+
+define <vscale x 8 x float> @vfsub_vf(<vscale x 8 x float> %va) {
+; CHECK-LABEL: vfsub_vf:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.s fa5, 2.0
+; CHECK-NEXT: vsetvli a0, zero, e32, m4, ta, ma
+; CHECK-NEXT: vfadd.vf v8, v8, fa5
+; CHECK-NEXT: ret
+ %vd = fsub <vscale x 8 x float> %va, splat (float -2.000000e+00)
+ ret <vscale x 8 x float> %vd
+}
>From ce7cbf9a54960727f8072cff5fa20cbe653389a9 Mon Sep 17 00:00:00 2001
From: Liao Chunyu <chunyu at iscas.ac.cn>
Date: Sun, 4 Jan 2026 09:07:42 +0000
Subject: [PATCH 05/11] Revert "[DAG]Add splat_vector to
TargetLowering::getNegatedExpression"
This reverts commit 30f4c8f230eee7b3d76b43af781bfdf1b3d2454c.
---
llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | 13 -------------
llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll | 14 ++------------
2 files changed, 2 insertions(+), 25 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 8e2aa3180fba5..94464e792c645 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -7554,19 +7554,6 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
Cost = NegatibleCost::Neutral;
return CFP;
}
- case ISD::SPLAT_VECTOR: {
- SDValue X = Op.getOperand(0);
- if (!isOperationLegal(ISD::SPLAT_VECTOR, VT))
- break;
-
- NegatibleCost CostX = NegatibleCost::Expensive;
- SDValue NegX =
- getNegatedExpression(X, DAG, LegalOps, OptForSize, CostX, Depth);
- if (!NegX || CostX >= NegatibleCost::Neutral)
- break;
- Cost = CostX;
- return DAG.getNode(ISD::SPLAT_VECTOR, DL, VT, NegX);
- }
case ISD::BUILD_VECTOR: {
// Only permit BUILD_VECTOR of constants.
if (llvm::any_of(Op->op_values(), [&](SDValue N) {
diff --git a/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll b/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
index bc91d620d0814..532d165791fa0 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
@@ -84,20 +84,10 @@ 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: vsetvli a0, zero, e32, m4, ta, ma
-; 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
-}
-
-define <vscale x 8 x float> @vfsub_vf(<vscale x 8 x float> %va) {
-; CHECK-LABEL: vfsub_vf:
-; 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 = fsub <vscale x 8 x float> %va, splat (float -2.000000e+00)
+ %vd = fadd <vscale x 8 x float> %va, splat (float -2.000000e+00)
ret <vscale x 8 x float> %vd
}
>From eeef94802d4ff411e8f6af2828876df9bf6cebe0 Mon Sep 17 00:00:00 2001
From: Liao Chunyu <chunyu at iscas.ac.cn>
Date: Mon, 5 Jan 2026 02:58:13 +0000
Subject: [PATCH 06/11] [DAGCombine]Fold (fadd A, Splat(fneg(B))) -> (fsub A,
Splat(B)) At the same time,fold (fsub A, Splat(fneg(B))) -> (fadd A,
Splat(B))
---
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 25 +++++++++++++++++++
llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll | 15 +++++++++--
2 files changed, 38 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index ee28260a74127..4fc0e85af7b25 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -18038,6 +18038,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;
@@ -18278,6 +18291,18 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) {
TLI.getNegatedExpression(N1, DAG, LegalOperations, ForCodeSize))
return DAG.getNode(ISD::FADD, DL, VT, N0, NegN1);
+ // fold (fsub A, Splat(fneg(B))) -> (fadd A, Splat(B))
+ if (VT.isVector() &&
+ (!LegalOperations || TLI.isOperationLegalOrCustom(ISD::FADD, 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::FADD, DL, VT, N0, Splat);
+ }
+ }
+ }
// FSUB -> FMA combines:
if (SDValue Fused = visitFSUBForFMACombine<EmptyMatchContext>(N)) {
AddToWorklist(Fused.getNode());
diff --git a/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll b/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
index 532d165791fa0..b9f7e725405be 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
@@ -84,10 +84,21 @@ 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
}
+
+
+define <vscale x 8 x float> @vfsub_vf(<vscale x 8 x float> %va) {
+; CHECK-LABEL: vfsub_vf:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.s fa5, 2.0
+; CHECK-NEXT: vsetvli a0, zero, e32, m4, ta, ma
+; CHECK-NEXT: vfadd.vf v8, v8, fa5
+; CHECK-NEXT: ret
+ %vd = fsub <vscale x 8 x float> %va, splat (float -2.000000e+00)
+ ret <vscale x 8 x float> %vd
+}
>From 3511e98ac18fae2fcfcfaa906d8b9bc35ad94278 Mon Sep 17 00:00:00 2001
From: Liao Chunyu <chunyu at iscas.ac.cn>
Date: Mon, 5 Jan 2026 03:11:51 +0000
Subject: [PATCH 07/11] Add TLI.isFNegFree(VT)
---
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 4fc0e85af7b25..38728427cb837 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -18043,7 +18043,8 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
(!LegalOperations || TLI.isOperationLegalOrCustom(ISD::FSUB, VT))) {
if (N1.getOpcode() == ISD::SPLAT_VECTOR) {
SDValue SplatN0 = N1->getOperand(0);
- if (SplatN0.getOpcode() == ISD::FNEG && SplatN0.hasOneUse()) {
+ if (SplatN0.getOpcode() == ISD::FNEG &&
+ (TLI.isFNegFree(VT) || SplatN0.hasOneUse())) {
SDValue Splat =
DAG.getNode(ISD::SPLAT_VECTOR, DL, VT, SplatN0->getOperand(0));
return DAG.getNode(ISD::FSUB, DL, VT, N0, Splat);
@@ -18296,7 +18297,8 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) {
(!LegalOperations || TLI.isOperationLegalOrCustom(ISD::FADD, VT))) {
if (N1.getOpcode() == ISD::SPLAT_VECTOR) {
SDValue SplatN0 = N1->getOperand(0);
- if (SplatN0.getOpcode() == ISD::FNEG && SplatN0.hasOneUse()) {
+ if (SplatN0.getOpcode() == ISD::FNEG &&
+ (TLI.isFNegFree(VT) || SplatN0.hasOneUse())) {
SDValue Splat =
DAG.getNode(ISD::SPLAT_VECTOR, DL, VT, SplatN0->getOperand(0));
return DAG.getNode(ISD::FADD, DL, VT, N0, Splat);
>From 8d5703d0439e3728bc3c39d7b9771380f683d20c Mon Sep 17 00:00:00 2001
From: Liao Chunyu <chunyu at iscas.ac.cn>
Date: Wed, 7 Jan 2026 01:33:05 +0000
Subject: [PATCH 08/11] Revert "Add TLI.isFNegFree(VT)"
This reverts commit 5649f0ae622474142b9ed13f0df09b374b4a5a81.
---
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 38728427cb837..4fc0e85af7b25 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -18043,8 +18043,7 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
(!LegalOperations || TLI.isOperationLegalOrCustom(ISD::FSUB, VT))) {
if (N1.getOpcode() == ISD::SPLAT_VECTOR) {
SDValue SplatN0 = N1->getOperand(0);
- if (SplatN0.getOpcode() == ISD::FNEG &&
- (TLI.isFNegFree(VT) || SplatN0.hasOneUse())) {
+ 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);
@@ -18297,8 +18296,7 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) {
(!LegalOperations || TLI.isOperationLegalOrCustom(ISD::FADD, VT))) {
if (N1.getOpcode() == ISD::SPLAT_VECTOR) {
SDValue SplatN0 = N1->getOperand(0);
- if (SplatN0.getOpcode() == ISD::FNEG &&
- (TLI.isFNegFree(VT) || SplatN0.hasOneUse())) {
+ if (SplatN0.getOpcode() == ISD::FNEG && SplatN0.hasOneUse()) {
SDValue Splat =
DAG.getNode(ISD::SPLAT_VECTOR, DL, VT, SplatN0->getOperand(0));
return DAG.getNode(ISD::FADD, DL, VT, N0, Splat);
>From ec0fe7645de266fe7b877489d8e6dbfc95249bcf Mon Sep 17 00:00:00 2001
From: Liao Chunyu <chunyu at iscas.ac.cn>
Date: Wed, 7 Jan 2026 01:33:16 +0000
Subject: [PATCH 09/11] Revert "[DAGCombine]Fold (fadd A, Splat(fneg(B))) ->
(fsub A, Splat(B))"
This reverts commit 4937d222e08a7a7a604920b7a443300be47a461f.
---
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 25 -------------------
llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll | 15 ++---------
2 files changed, 2 insertions(+), 38 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 4fc0e85af7b25..ee28260a74127 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -18038,19 +18038,6 @@ 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;
@@ -18291,18 +18278,6 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) {
TLI.getNegatedExpression(N1, DAG, LegalOperations, ForCodeSize))
return DAG.getNode(ISD::FADD, DL, VT, N0, NegN1);
- // fold (fsub A, Splat(fneg(B))) -> (fadd A, Splat(B))
- if (VT.isVector() &&
- (!LegalOperations || TLI.isOperationLegalOrCustom(ISD::FADD, 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::FADD, DL, VT, N0, Splat);
- }
- }
- }
// FSUB -> FMA combines:
if (SDValue Fused = visitFSUBForFMACombine<EmptyMatchContext>(N)) {
AddToWorklist(Fused.getNode());
diff --git a/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll b/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
index b9f7e725405be..532d165791fa0 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
@@ -84,21 +84,10 @@ 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: vsetvli a0, zero, e32, m4, ta, ma
-; 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
-}
-
-
-define <vscale x 8 x float> @vfsub_vf(<vscale x 8 x float> %va) {
-; CHECK-LABEL: vfsub_vf:
-; 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 = fsub <vscale x 8 x float> %va, splat (float -2.000000e+00)
+ %vd = fadd <vscale x 8 x float> %va, splat (float -2.000000e+00)
ret <vscale x 8 x float> %vd
}
>From 4fbb519cc2bcc8c2ee8077692f742120d90a2a55 Mon Sep 17 00:00:00 2001
From: Liao Chunyu <chunyu at iscas.ac.cn>
Date: Wed, 7 Jan 2026 02:05:13 +0000
Subject: [PATCH 10/11] [DAGCombine]Fold (fadd A, Splat(fneg(B))) -> (fsub A,
Splat(B)) Fold (fsub A, Splat(fneg(B))) -> (fadd A, Splat(B))
---
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 22 +++++++++++++++++++
llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll | 15 +++++++++++--
2 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index ee28260a74127..69a340e3d9daa 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -18038,6 +18038,17 @@ 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 (N1.getOpcode() == ISD::SPLAT_VECTOR) {
+ SDValue SplatN0 = N1->getOperand(0);
+ if (SDValue NegN0 = TLI.getCheaperNegatedExpression(
+ SplatN0, DAG, LegalOperations, ForCodeSize)) {
+ 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;
@@ -18278,6 +18289,17 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) {
TLI.getNegatedExpression(N1, DAG, LegalOperations, ForCodeSize))
return DAG.getNode(ISD::FADD, DL, VT, N0, NegN1);
+ // fold (fsub A, Splat(fneg(B))) -> (fadd A, Splat(B))
+ if (N1.getOpcode() == ISD::SPLAT_VECTOR) {
+ SDValue SplatN0 = N1->getOperand(0);
+ if (SDValue NegN0 = TLI.getCheaperNegatedExpression(
+ SplatN0, DAG, LegalOperations, ForCodeSize)) {
+ SDValue Splat =
+ DAG.getNode(ISD::SPLAT_VECTOR, DL, VT, SplatN0->getOperand(0));
+ return DAG.getNode(ISD::FADD, DL, VT, N0, Splat);
+ }
+ }
+
// FSUB -> FMA combines:
if (SDValue Fused = visitFSUBForFMACombine<EmptyMatchContext>(N)) {
AddToWorklist(Fused.getNode());
diff --git a/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll b/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
index 532d165791fa0..b9f7e725405be 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vsplats-zfa.ll
@@ -84,10 +84,21 @@ 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
}
+
+
+define <vscale x 8 x float> @vfsub_vf(<vscale x 8 x float> %va) {
+; CHECK-LABEL: vfsub_vf:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fli.s fa5, 2.0
+; CHECK-NEXT: vsetvli a0, zero, e32, m4, ta, ma
+; CHECK-NEXT: vfadd.vf v8, v8, fa5
+; CHECK-NEXT: ret
+ %vd = fsub <vscale x 8 x float> %va, splat (float -2.000000e+00)
+ ret <vscale x 8 x float> %vd
+}
>From 9b4a5c25c4407d8e00cc9cba39073921eca53ead Mon Sep 17 00:00:00 2001
From: Liao Chunyu <chunyu at iscas.ac.cn>
Date: Thu, 8 Jan 2026 02:18:42 +0000
Subject: [PATCH 11/11] Add todo for ISD::SPLAT_VECTOR
---
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 69a340e3d9daa..a8bd8914665aa 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -18039,6 +18039,7 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
return DAG.getNode(ISD::FSUB, DL, VT, N1, NegN0);
// fold (fadd A, Splat(fneg(B))) -> (fsub A, Splat(B))
+ // TODO: move ISD::SPLAT_VECTOR handling inside getCheaperNegatedExpression
if (N1.getOpcode() == ISD::SPLAT_VECTOR) {
SDValue SplatN0 = N1->getOperand(0);
if (SDValue NegN0 = TLI.getCheaperNegatedExpression(
@@ -18290,6 +18291,7 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) {
return DAG.getNode(ISD::FADD, DL, VT, N0, NegN1);
// fold (fsub A, Splat(fneg(B))) -> (fadd A, Splat(B))
+ // TODO: move ISD::SPLAT_VECTOR handling inside getCheaperNegatedExpression
if (N1.getOpcode() == ISD::SPLAT_VECTOR) {
SDValue SplatN0 = N1->getOperand(0);
if (SDValue NegN0 = TLI.getCheaperNegatedExpression(
More information about the llvm-commits
mailing list