[llvm] [Reassociate]Reject fma pairs with a shared addend (PR #228751)
Alexey Bataev via llvm-commits
llvm-commits at lists.llvm.org
Sat Oct 3 10:47:00 PDT 2026
https://github.com/alexey-bataev created https://github.com/llvm/llvm-project/pull/228751
A kept pair whose addend has other uses is frozen against the rank based
re-sort of the enclosing expression. That hides the shared value from the
other terms and turns b + c*c + b*b + c into two independent pairs instead
of the chain produced before #215873. Fixes the TSVC s1244 regression left
over after #220640.
Assisted-by: Cursor
>From 0b9bee4eec15d2a77ff59b1756acc29d2bb1e0dd Mon Sep 17 00:00:00 2001
From: Alexey Bataev <a.bataev at outlook.com>
Date: Sat, 3 Oct 2026 10:46:45 -0700
Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?=
=?UTF-8?q?l=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.7
---
llvm/lib/Transforms/Scalar/Reassociate.cpp | 9 ++--
llvm/test/Transforms/Reassociate/fma-pairs.ll | 54 +++++++++++++++++++
2 files changed, 59 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/Reassociate.cpp b/llvm/lib/Transforms/Scalar/Reassociate.cpp
index 5e5b0a8ae1d8f4..7963201785086f 100644
--- a/llvm/lib/Transforms/Scalar/Reassociate.cpp
+++ b/llvm/lib/Transforms/Scalar/Reassociate.cpp
@@ -196,12 +196,13 @@ static BinaryOperator *isFMulAddCandidate(Value *V) {
};
BinaryOperator *Mul = nullptr;
Value *OtherOp = nullptr;
- // Keep constants, nested additions and other contractible multiplies visible
- // to the enclosing expression so they can participate in folding,
- // reassociation and factorization.
+ // Keep constants, nested additions, other contractible multiplies and shared
+ // addends visible to the enclosing expression so they can participate in
+ // folding, reassociation and factorization.
if (!match(FAdd, m_c_FAdd(ContractableFMul(Mul), m_Value(OtherOp))) ||
isa<Constant>(OtherOp) || isReassociableOp(OtherOp, Instruction::FAdd) ||
- match(OtherOp, m_AllowContract(m_FMul(m_Value(), m_Value()))))
+ match(OtherOp, m_AllowContract(m_FMul(m_Value(), m_Value()))) ||
+ !OtherOp->hasOneUse())
return nullptr;
return Mul;
}
diff --git a/llvm/test/Transforms/Reassociate/fma-pairs.ll b/llvm/test/Transforms/Reassociate/fma-pairs.ll
index f7c9c9b86e730f..79bf70ad1a51b7 100644
--- a/llvm/test/Transforms/Reassociate/fma-pairs.ll
+++ b/llvm/test/Transforms/Reassociate/fma-pairs.ll
@@ -480,3 +480,57 @@ define float @multi_use_fmul_addend(float %a, float %c, float %d, float %e, floa
%r = fadd fast float %t1, %t2
ret float %r
}
+
+define float @shared_addend_chain(float %b, float %c) {
+; CHECK-LABEL: define float @shared_addend_chain(
+; CHECK-SAME: float [[B:%.*]], float [[C:%.*]]) {
+; CHECK-NEXT: [[CC:%.*]] = fmul fast float [[C]], [[C]]
+; CHECK-NEXT: [[BB:%.*]] = fmul fast float [[B]], [[B]]
+; CHECK-NEXT: [[B_CC:%.*]] = fadd fast float [[BB]], [[B]]
+; CHECK-NEXT: [[SUM0:%.*]] = fadd fast float [[B_CC]], [[C]]
+; CHECK-NEXT: [[SUM:%.*]] = fadd fast float [[SUM0]], [[CC]]
+; CHECK-NEXT: ret float [[SUM]]
+;
+ %cc = fmul fast float %c, %c
+ %b.cc = fadd fast float %b, %cc
+ %bb = fmul fast float %b, %b
+ %sum0 = fadd fast float %b.cc, %bb
+ %sum = fadd fast float %sum0, %c
+ ret float %sum
+}
+
+define float @shared_addend_pairs(float %b, float %c) {
+; CHECK-LABEL: define float @shared_addend_pairs(
+; CHECK-SAME: float [[B:%.*]], float [[C:%.*]]) {
+; CHECK-NEXT: [[BB:%.*]] = fmul fast float [[B]], [[B]]
+; CHECK-NEXT: [[CC:%.*]] = fmul fast float [[C]], [[C]]
+; CHECK-NEXT: [[B_CC:%.*]] = fadd fast float [[BB]], [[B]]
+; CHECK-NEXT: [[C_BB:%.*]] = fadd fast float [[B_CC]], [[C]]
+; CHECK-NEXT: [[SUM:%.*]] = fadd fast float [[C_BB]], [[CC]]
+; CHECK-NEXT: ret float [[SUM]]
+;
+ %bb = fmul fast float %b, %b
+ %cc = fmul fast float %c, %c
+ %b.cc = fadd fast float %b, %cc
+ %c.bb = fadd fast float %c, %bb
+ %sum = fadd fast float %b.cc, %c.bb
+ ret float %sum
+}
+
+define float @shared_addend_non_square(float %b, float %c, float %d, float %e) {
+; CHECK-LABEL: define float @shared_addend_non_square(
+; CHECK-SAME: float [[B:%.*]], float [[C:%.*]], float [[D:%.*]], float [[E:%.*]]) {
+; CHECK-NEXT: [[CD:%.*]] = fmul fast float [[D]], [[C]]
+; CHECK-NEXT: [[BE:%.*]] = fmul fast float [[E]], [[B]]
+; CHECK-NEXT: [[B_CD:%.*]] = fadd fast float [[C]], [[B]]
+; CHECK-NEXT: [[SUM0:%.*]] = fadd fast float [[B_CD]], [[CD]]
+; CHECK-NEXT: [[SUM:%.*]] = fadd fast float [[SUM0]], [[BE]]
+; CHECK-NEXT: ret float [[SUM]]
+;
+ %cd = fmul fast float %c, %d
+ %b.cd = fadd fast float %b, %cd
+ %be = fmul fast float %b, %e
+ %sum0 = fadd fast float %b.cd, %be
+ %sum = fadd fast float %sum0, %c
+ ret float %sum
+}
More information about the llvm-commits
mailing list