[llvm] [RISCV] Propagate SDNode flags when combining `(fmul (fneg X), ...)` (PR #169460)
Min-Yih Hsu via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 25 09:19:45 PST 2025
https://github.com/mshockwave updated https://github.com/llvm/llvm-project/pull/169460
>From 95836edcf595b39d12a508bbc7321cf6adec1b12 Mon Sep 17 00:00:00 2001
From: Min-Yih Hsu <min.hsu at sifive.com>
Date: Mon, 24 Nov 2025 22:34:30 -0800
Subject: [PATCH 1/3] Pre-commit test
---
llvm/test/CodeGen/RISCV/fma-combine.ll | 56 ++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
create mode 100644 llvm/test/CodeGen/RISCV/fma-combine.ll
diff --git a/llvm/test/CodeGen/RISCV/fma-combine.ll b/llvm/test/CodeGen/RISCV/fma-combine.ll
new file mode 100644
index 0000000000000..d0f2d6732ce2d
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/fma-combine.ll
@@ -0,0 +1,56 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=riscv64 -mattr='+d,+m' < %s | FileCheck %s
+
+define double @fnmadd_non_trivial(ptr %p0, ptr %p1, ptr %dst, double %mul425) {
+; CHECK-LABEL: fnmadd_non_trivial:
+; CHECK: # %bb.0:
+; CHECK-NEXT: li a3, -2047
+; CHECK-NEXT: slli a3, a3, 51
+; CHECK-NEXT: fmv.d.x fa5, a3
+; CHECK-NEXT: lui a3, 2049
+; CHECK-NEXT: slli a3, a3, 39
+; CHECK-NEXT: fmv.d.x fa4, a3
+; CHECK-NEXT: lui a3, 8201
+; CHECK-NEXT: fmv.d.x fa3, zero
+; CHECK-NEXT: slli a3, a3, 37
+; CHECK-NEXT: fmv.d.x fa2, a3
+; CHECK-NEXT: li a3, 1023
+; CHECK-NEXT: slli a3, a3, 52
+; CHECK-NEXT: fsub.d fa1, fa3, fa0
+; CHECK-NEXT: fmadd.d fa1, fa1, fa2, fa4
+; CHECK-NEXT: fmadd.d fa4, fa0, fa2, fa4
+; CHECK-NEXT: fmv.d.x fa2, a3
+; CHECK-NEXT: lui a3, %hi(.LCPI0_0)
+; CHECK-NEXT: ld a3, %lo(.LCPI0_0)(a3)
+; CHECK-NEXT: fmul.d fa5, fa0, fa5
+; CHECK-NEXT: fmul.d fa4, fa4, fa3
+; CHECK-NEXT: fmul.d fa1, fa1, fa3
+; CHECK-NEXT: sd a3, 0(a2)
+; CHECK-NEXT: fsd fa5, 0(a0)
+; CHECK-NEXT: fneg.d fa5, fa4
+; CHECK-NEXT: fneg.d fa4, fa1
+; CHECK-NEXT: fsub.d fa5, fa5, fa2
+; CHECK-NEXT: fsub.d fa4, fa4, fa2
+; CHECK-NEXT: fnmadd.d fa5, fa5, fa3, fa0
+; CHECK-NEXT: fnmadd.d fa0, fa0, fa3, fa4
+; CHECK-NEXT: fsd fa5, 0(a1)
+; CHECK-NEXT: ret
+ store double 0x3FEE666666666666, ptr %dst, align 8
+ %mul413 = fmul double %mul425, -3.000000e+00
+ store double %mul413, ptr %p0, align 8
+ %mul428 = fmul contract double %mul425, 4.500000e+00
+ %add429 = fadd nsz contract double %mul428, 3.000000e+00
+ %mul430 = fmul contract double %add429, 0.000000e+00
+ %sub432 = fadd nsz contract double %mul430, 1.000000e+00
+ %mul433 = fmul contract double %sub432, 0.000000e+00
+ %1 = fsub nsz contract double %mul433, %mul425
+ store double %1, ptr %p1, align 8
+ %mul441 = fmul contract double %mul425, 0.000000e+00
+ %add443 = fsub double 0.000000e+00, %mul425
+ %mul446 = fmul contract double %add443, 4.500000e+00
+ %add447 = fadd nsz contract double %mul446, 3.000000e+00
+ %mul448 = fmul contract double %add447, 0.000000e+00
+ %sub450 = fadd nsz contract double %mul448, 1.000000e+00
+ %2 = fsub nsz contract double %sub450, %mul441
+ ret double %2
+}
>From 699229300cec86a575b4ffeadbde8f0ba0547db7 Mon Sep 17 00:00:00 2001
From: Min-Yih Hsu <min.hsu at sifive.com>
Date: Mon, 24 Nov 2025 22:34:40 -0800
Subject: [PATCH 2/3] [RISCV] Propagate SDNode flags when combining `(fmul
(fneg ...))`
Co-Authored-By: Craig Topper <craig.topper at sifive.com>
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 2 +-
llvm/test/CodeGen/RISCV/fma-combine.ll | 24 +++++++++------------
2 files changed, 11 insertions(+), 15 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 19a16197272fe..53293fb093ccd 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -20822,7 +20822,7 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
// Undo this and sink the fneg so we match more fmsub/fnmadd patterns.
if (sd_match(N, m_FMul(m_Value(X), m_OneUse(m_FNeg(m_Value(Y))))))
return DAG.getNode(ISD::FNEG, DL, VT,
- DAG.getNode(ISD::FMUL, DL, VT, X, Y));
+ DAG.getNode(ISD::FMUL, DL, VT, X, Y, N->getFlags()));
// fmul X, (copysign 1.0, Y) -> fsgnjx X, Y
SDValue N0 = N->getOperand(0);
diff --git a/llvm/test/CodeGen/RISCV/fma-combine.ll b/llvm/test/CodeGen/RISCV/fma-combine.ll
index d0f2d6732ce2d..67d3175718072 100644
--- a/llvm/test/CodeGen/RISCV/fma-combine.ll
+++ b/llvm/test/CodeGen/RISCV/fma-combine.ll
@@ -11,28 +11,24 @@ define double @fnmadd_non_trivial(ptr %p0, ptr %p1, ptr %dst, double %mul425) {
; CHECK-NEXT: slli a3, a3, 39
; CHECK-NEXT: fmv.d.x fa4, a3
; CHECK-NEXT: lui a3, 8201
-; CHECK-NEXT: fmv.d.x fa3, zero
; CHECK-NEXT: slli a3, a3, 37
-; CHECK-NEXT: fmv.d.x fa2, a3
+; CHECK-NEXT: fmv.d.x fa3, a3
; CHECK-NEXT: li a3, 1023
+; CHECK-NEXT: fmv.d.x fa2, zero
; CHECK-NEXT: slli a3, a3, 52
-; CHECK-NEXT: fsub.d fa1, fa3, fa0
-; CHECK-NEXT: fmadd.d fa1, fa1, fa2, fa4
-; CHECK-NEXT: fmadd.d fa4, fa0, fa2, fa4
-; CHECK-NEXT: fmv.d.x fa2, a3
+; CHECK-NEXT: fsub.d fa1, fa2, fa0
+; CHECK-NEXT: fmadd.d fa1, fa1, fa3, fa4
+; CHECK-NEXT: fmadd.d fa4, fa0, fa3, fa4
+; CHECK-NEXT: fmv.d.x fa3, a3
; CHECK-NEXT: lui a3, %hi(.LCPI0_0)
; CHECK-NEXT: ld a3, %lo(.LCPI0_0)(a3)
; CHECK-NEXT: fmul.d fa5, fa0, fa5
-; CHECK-NEXT: fmul.d fa4, fa4, fa3
-; CHECK-NEXT: fmul.d fa1, fa1, fa3
+; CHECK-NEXT: fnmadd.d fa4, fa4, fa2, fa3
+; CHECK-NEXT: fnmadd.d fa3, fa1, fa2, fa3
; CHECK-NEXT: sd a3, 0(a2)
; CHECK-NEXT: fsd fa5, 0(a0)
-; CHECK-NEXT: fneg.d fa5, fa4
-; CHECK-NEXT: fneg.d fa4, fa1
-; CHECK-NEXT: fsub.d fa5, fa5, fa2
-; CHECK-NEXT: fsub.d fa4, fa4, fa2
-; CHECK-NEXT: fnmadd.d fa5, fa5, fa3, fa0
-; CHECK-NEXT: fnmadd.d fa0, fa0, fa3, fa4
+; CHECK-NEXT: fnmadd.d fa5, fa4, fa2, fa0
+; CHECK-NEXT: fnmadd.d fa0, fa0, fa2, fa3
; CHECK-NEXT: fsd fa5, 0(a1)
; CHECK-NEXT: ret
store double 0x3FEE666666666666, ptr %dst, align 8
>From 98be56064b423b8c1dc5555dfc17629406c7a6fd Mon Sep 17 00:00:00 2001
From: Min-Yih Hsu <min.hsu at sifive.com>
Date: Tue, 25 Nov 2025 09:19:17 -0800
Subject: [PATCH 3/3] fixup! Address review comments
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 3 ++-
llvm/test/CodeGen/RISCV/fma-combine.ll | 4 ++++
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 53293fb093ccd..3b250d7d9ad1f 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -20822,7 +20822,8 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
// Undo this and sink the fneg so we match more fmsub/fnmadd patterns.
if (sd_match(N, m_FMul(m_Value(X), m_OneUse(m_FNeg(m_Value(Y))))))
return DAG.getNode(ISD::FNEG, DL, VT,
- DAG.getNode(ISD::FMUL, DL, VT, X, Y, N->getFlags()));
+ DAG.getNode(ISD::FMUL, DL, VT, X, Y, N->getFlags()),
+ N->getFlags());
// fmul X, (copysign 1.0, Y) -> fsgnjx X, Y
SDValue N0 = N->getOperand(0);
diff --git a/llvm/test/CodeGen/RISCV/fma-combine.ll b/llvm/test/CodeGen/RISCV/fma-combine.ll
index 67d3175718072..beffecca4dc1e 100644
--- a/llvm/test/CodeGen/RISCV/fma-combine.ll
+++ b/llvm/test/CodeGen/RISCV/fma-combine.ll
@@ -1,6 +1,10 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
; RUN: llc -mtriple=riscv64 -mattr='+d,+m' < %s | FileCheck %s
+; What the original PR (#169460) tried to solve can only be revealed when a specific
+; set of FMA DAG combiner patterns were skipped due to hitting some recursion limits.
+; And this test is written in a way to hit that limit.
+
define double @fnmadd_non_trivial(ptr %p0, ptr %p1, ptr %dst, double %mul425) {
; CHECK-LABEL: fnmadd_non_trivial:
; CHECK: # %bb.0:
More information about the llvm-commits
mailing list