[llvm] [Reassociate]Reject fma pairs with a shared addend (PR #228751)

via llvm-commits llvm-commits at lists.llvm.org
Sat Oct 3 10:47:46 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Alexey Bataev (alexey-bataev)

<details>
<summary>Changes</summary>

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


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


2 Files Affected:

- (modified) llvm/lib/Transforms/Scalar/Reassociate.cpp (+5-4) 
- (modified) llvm/test/Transforms/Reassociate/fma-pairs.ll (+54) 


``````````diff
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
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/228751


More information about the llvm-commits mailing list