[flang-commits] [flang] [flang] Join reassociated sums with the head first (PR #223966)

via flang-commits flang-commits at lists.llvm.org
Wed Sep 16 03:28:19 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-openacc

Author: Tom Eccles (tblah)

<details>
<summary>Changes</summary>

After #<!-- -->222302 we saw a small regression in bwaves with -ffast-math on some CI machines. I'm quite surprised that this expression ordering has any effect when reassociation is enabled in the middle-end. The change in this commit is a bit arbitrary but it restores bwaves performance without regressing anything else.

Keep the first two terms in the left operand of the final signed join. Retain both right-associated folds and the existing eligibility guards. This preserves the source order between the two groups, allowing a head-first alternative to the code shape produced by tail-first joining.

Update lowering order checks and use four terms in nested-expression coverage so enabled reassociation remains distinct from the opt-out.

---

Patch is 36.90 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/223966.diff


4 Files Affected:

- (modified) flang/lib/Evaluate/tools.cpp (+1-1) 
- (modified) flang/test/Lower/OpenACC/acc-cache.f90 (+1-1) 
- (modified) flang/test/Lower/split-sum-expression-tree-lowering.f90 (+216-184) 
- (modified) flang/test/Lower/split-sum-expression-tree-subscripts.f90 (+10-10) 


``````````diff
diff --git a/flang/lib/Evaluate/tools.cpp b/flang/lib/Evaluate/tools.cpp
index def85232cc572f..f368335e82ddd8 100644
--- a/flang/lib/Evaluate/tools.cpp
+++ b/flang/lib/Evaluate/tools.cpp
@@ -1531,7 +1531,7 @@ static std::optional<NumericExpr<CAT, KIND>> tryBuildSplitSumExpressionTree(
   SignedNumericExpr<CAT, KIND> headExpr = buildRightAssociatedSignedFold(head);
   SignedNumericExpr<CAT, KIND> tailExpr = buildRightAssociatedSignedFold(tail);
   SignedNumericExpr<CAT, KIND> result =
-      buildSignedAdd(std::move(tailExpr), std::move(headExpr));
+      buildSignedAdd(std::move(headExpr), std::move(tailExpr));
   assert(result.isPositive &&
       "the first flattened term and therefore the split sum are positive");
   return std::move(result.expr);
diff --git a/flang/test/Lower/OpenACC/acc-cache.f90 b/flang/test/Lower/OpenACC/acc-cache.f90
index 9bdacc17cd9847..12bdee38338705 100644
--- a/flang/test/Lower/OpenACC/acc-cache.f90
+++ b/flang/test/Lower/OpenACC/acc-cache.f90
@@ -212,10 +212,10 @@ subroutine test_cache_loop_var()
 ! CHECK: fir.load
 ! CHECK: hlfir.designate %[[DECL]]#0
 ! CHECK: fir.load
+! CHECK: arith.addf
 ! CHECK: hlfir.designate %[[DECL]]#0
 ! CHECK: fir.load
 ! CHECK: arith.addf
-! CHECK: arith.addf
 ! CHECK: hlfir.assign
 ! Scope termination
 ! CHECK: acc.yield
diff --git a/flang/test/Lower/split-sum-expression-tree-lowering.f90 b/flang/test/Lower/split-sum-expression-tree-lowering.f90
index 7d418d09cc3198..8ffb5baae47db2 100644
--- a/flang/test/Lower/split-sum-expression-tree-lowering.f90
+++ b/flang/test/Lower/split-sum-expression-tree-lowering.f90
@@ -6,7 +6,7 @@
 ! RUN: bbc -emit-hlfir -ffp-sum-reassociation=false -o - %s | FileCheck %s --check-prefixes=DEFAULT,NO-REWRITE
 
 ! Default:   (((x + a*b) + c*d) + e*f)
-! Rewritten: ((c*d + e*f) + (x + a*b))
+! Rewritten: ((x + a*b) + (c*d + e*f))
 subroutine eligible_self_update3(x,a,b,c,d,e,f)
   real(8) :: x,a,b,c,d,e,f
   x = x + a*b + c*d + e*f
@@ -20,6 +20,11 @@ subroutine eligible_self_update3(x,a,b,c,d,e,f)
 ! SPLIT-DAG: %[[E:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_self_update3Ee"}
 ! SPLIT-DAG: %[[F:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_self_update3Ef"}
 ! SPLIT-DAG: %[[X:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_self_update3Ex"}
+! SPLIT: %[[XV:.*]] = fir.load %[[X]]#0
+! SPLIT: %[[AV:.*]] = fir.load %[[A]]#0
+! SPLIT: %[[BV:.*]] = fir.load %[[B]]#0
+! SPLIT: %[[AB:.*]] = arith.mulf %[[AV]], %[[BV]]
+! SPLIT: %[[HEAD:.*]] = arith.addf %[[XV]], %[[AB]]
 ! SPLIT: %[[CV:.*]] = fir.load %[[C]]#0
 ! SPLIT: %[[DV:.*]] = fir.load %[[D]]#0
 ! SPLIT: %[[CD:.*]] = arith.mulf %[[CV]], %[[DV]]
@@ -27,13 +32,8 @@ subroutine eligible_self_update3(x,a,b,c,d,e,f)
 ! SPLIT: %[[FV:.*]] = fir.load %[[F]]#0
 ! SPLIT: %[[EF:.*]] = arith.mulf %[[EV]], %[[FV]]
 ! SPLIT: %[[TAIL:.*]] = arith.addf %[[CD]], %[[EF]]
-! SPLIT: %[[XV:.*]] = fir.load %[[X]]#0
-! SPLIT: %[[AV:.*]] = fir.load %[[A]]#0
-! SPLIT: %[[BV:.*]] = fir.load %[[B]]#0
-! SPLIT: %[[AB:.*]] = arith.mulf %[[AV]], %[[BV]]
-! SPLIT: %[[HEAD:.*]] = arith.addf %[[XV]], %[[AB]]
 ! SPLIT-NOT: arith.addf %[[HEAD]], %[[CD]]
-! SPLIT: %[[RES:.*]] = arith.addf %[[TAIL]], %[[HEAD]]
+! SPLIT: %[[RES:.*]] = arith.addf %[[HEAD]], %[[TAIL]]
 ! SPLIT: hlfir.assign %[[RES]] to %[[X]]#0
 
 ! DEFAULT-LABEL: func.func @_QPeligible_self_update3
@@ -60,7 +60,7 @@ subroutine eligible_self_update3(x,a,b,c,d,e,f)
 ! DEFAULT: hlfir.assign %[[RES]] to %[[X]]#0
 
 ! Default:   ((((x + a*b) + c*d) + e*f) + g*h)
-! Rewritten: ((c*d + (e*f + g*h)) + (x + a*b))
+! Rewritten: ((x + a*b) + (c*d + (e*f + g*h)))
 subroutine eligible_self_update4(x,a,b,c,d,e,f,g,h)
   real(8) :: x,a,b,c,d,e,f,g,h
   x = x + a*b + c*d + e*f + g*h
@@ -76,6 +76,11 @@ subroutine eligible_self_update4(x,a,b,c,d,e,f,g,h)
 ! SPLIT-DAG: %[[G:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_self_update4Eg"}
 ! SPLIT-DAG: %[[H:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_self_update4Eh"}
 ! SPLIT-DAG: %[[X:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_self_update4Ex"}
+! SPLIT: %[[XV:.*]] = fir.load %[[X]]#0
+! SPLIT: %[[AV:.*]] = fir.load %[[A]]#0
+! SPLIT: %[[BV:.*]] = fir.load %[[B]]#0
+! SPLIT: %[[AB:.*]] = arith.mulf %[[AV]], %[[BV]]
+! SPLIT: %[[HEAD:.*]] = arith.addf %[[XV]], %[[AB]]
 ! SPLIT: %[[CV:.*]] = fir.load %[[C]]#0
 ! SPLIT: %[[DV:.*]] = fir.load %[[D]]#0
 ! SPLIT: %[[CD:.*]] = arith.mulf %[[CV]], %[[DV]]
@@ -87,13 +92,8 @@ subroutine eligible_self_update4(x,a,b,c,d,e,f,g,h)
 ! SPLIT: %[[GH:.*]] = arith.mulf %[[GV]], %[[HV]]
 ! SPLIT: %[[EFGH:.*]] = arith.addf %[[EF]], %[[GH]]
 ! SPLIT: %[[TAIL:.*]] = arith.addf %[[CD]], %[[EFGH]]
-! SPLIT: %[[XV:.*]] = fir.load %[[X]]#0
-! SPLIT: %[[AV:.*]] = fir.load %[[A]]#0
-! SPLIT: %[[BV:.*]] = fir.load %[[B]]#0
-! SPLIT: %[[AB:.*]] = arith.mulf %[[AV]], %[[BV]]
-! SPLIT: %[[HEAD:.*]] = arith.addf %[[XV]], %[[AB]]
 ! SPLIT-NOT: arith.addf %[[HEAD]], %[[CD]]
-! SPLIT: %[[RES:.*]] = arith.addf %[[TAIL]], %[[HEAD]]
+! SPLIT: %[[RES:.*]] = arith.addf %[[HEAD]], %[[TAIL]]
 ! SPLIT: hlfir.assign %[[RES]] to %[[X]]#0
 
 ! DEFAULT-LABEL: func.func @_QPeligible_self_update4
@@ -126,7 +126,7 @@ subroutine eligible_self_update4(x,a,b,c,d,e,f,g,h)
 ! DEFAULT: hlfir.assign %[[RES]] to %[[X]]#0
 
 ! Default:   (((a*b + c*d) + e*f) + g*h)
-! Rewritten: ((e*f + g*h) + (a*b + c*d))
+! Rewritten: ((a*b + c*d) + (e*f + g*h))
 subroutine eligible_out_of_place4(y,a,b,c,d,e,f,g,h)
   real(8) :: y,a,b,c,d,e,f,g,h
   y = a*b + c*d + e*f + g*h
@@ -142,13 +142,6 @@ subroutine eligible_out_of_place4(y,a,b,c,d,e,f,g,h)
 ! SPLIT-DAG: %[[G:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_out_of_place4Eg"}
 ! SPLIT-DAG: %[[H:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_out_of_place4Eh"}
 ! SPLIT-DAG: %[[Y:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_out_of_place4Ey"}
-! SPLIT: %[[EV:.*]] = fir.load %[[E]]#0
-! SPLIT: %[[FV:.*]] = fir.load %[[F]]#0
-! SPLIT: %[[EF:.*]] = arith.mulf %[[EV]], %[[FV]]
-! SPLIT: %[[GV:.*]] = fir.load %[[G]]#0
-! SPLIT: %[[HV:.*]] = fir.load %[[H]]#0
-! SPLIT: %[[GH:.*]] = arith.mulf %[[GV]], %[[HV]]
-! SPLIT: %[[TAIL:.*]] = arith.addf %[[EF]], %[[GH]]
 ! SPLIT: %[[AV:.*]] = fir.load %[[A]]#0
 ! SPLIT: %[[BV:.*]] = fir.load %[[B]]#0
 ! SPLIT: %[[AB:.*]] = arith.mulf %[[AV]], %[[BV]]
@@ -156,8 +149,15 @@ subroutine eligible_out_of_place4(y,a,b,c,d,e,f,g,h)
 ! SPLIT: %[[DV:.*]] = fir.load %[[D]]#0
 ! SPLIT: %[[CD:.*]] = arith.mulf %[[CV]], %[[DV]]
 ! SPLIT: %[[HEAD:.*]] = arith.addf %[[AB]], %[[CD]]
+! SPLIT: %[[EV:.*]] = fir.load %[[E]]#0
+! SPLIT: %[[FV:.*]] = fir.load %[[F]]#0
+! SPLIT: %[[EF:.*]] = arith.mulf %[[EV]], %[[FV]]
+! SPLIT: %[[GV:.*]] = fir.load %[[G]]#0
+! SPLIT: %[[HV:.*]] = fir.load %[[H]]#0
+! SPLIT: %[[GH:.*]] = arith.mulf %[[GV]], %[[HV]]
+! SPLIT: %[[TAIL:.*]] = arith.addf %[[EF]], %[[GH]]
 ! SPLIT-NOT: arith.addf %[[HEAD]], %[[EF]]
-! SPLIT: %[[RES:.*]] = arith.addf %[[TAIL]], %[[HEAD]]
+! SPLIT: %[[RES:.*]] = arith.addf %[[HEAD]], %[[TAIL]]
 ! SPLIT: hlfir.assign %[[RES]] to %[[Y]]#0
 
 ! DEFAULT-LABEL: func.func @_QPeligible_out_of_place4
@@ -188,7 +188,7 @@ subroutine eligible_out_of_place4(y,a,b,c,d,e,f,g,h)
 ! DEFAULT: hlfir.assign %[[RES]] to %[[Y]]#0
 
 ! Default:   (((x + a) + b*c) + d*e)
-! Rewritten: ((b*c + d*e) + (x + a))
+! Rewritten: ((x + a) + (b*c + d*e))
 subroutine eligible_scalar_term(x,a,b,c,d,e)
   real(8) :: x,a,b,c,d,e
   x = x + a + b*c + d*e
@@ -201,6 +201,9 @@ subroutine eligible_scalar_term(x,a,b,c,d,e)
 ! SPLIT-DAG: %[[D:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_scalar_termEd"}
 ! SPLIT-DAG: %[[E:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_scalar_termEe"}
 ! SPLIT-DAG: %[[X:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_scalar_termEx"}
+! SPLIT: %[[XV:.*]] = fir.load %[[X]]#0
+! SPLIT: %[[AV:.*]] = fir.load %[[A]]#0
+! SPLIT: %[[HEAD:.*]] = arith.addf %[[XV]], %[[AV]]
 ! SPLIT: %[[BV:.*]] = fir.load %[[B]]#0
 ! SPLIT: %[[CV:.*]] = fir.load %[[C]]#0
 ! SPLIT: %[[BC:.*]] = arith.mulf %[[BV]], %[[CV]]
@@ -208,11 +211,8 @@ subroutine eligible_scalar_term(x,a,b,c,d,e)
 ! SPLIT: %[[EV:.*]] = fir.load %[[E]]#0
 ! SPLIT: %[[DE:.*]] = arith.mulf %[[DV]], %[[EV]]
 ! SPLIT: %[[TAIL:.*]] = arith.addf %[[BC]], %[[DE]]
-! SPLIT: %[[XV:.*]] = fir.load %[[X]]#0
-! SPLIT: %[[AV:.*]] = fir.load %[[A]]#0
-! SPLIT: %[[HEAD:.*]] = arith.addf %[[XV]], %[[AV]]
 ! SPLIT-NOT: arith.addf %[[HEAD]], %[[BC]]
-! SPLIT: %[[RES:.*]] = arith.addf %[[TAIL]], %[[HEAD]]
+! SPLIT: %[[RES:.*]] = arith.addf %[[HEAD]], %[[TAIL]]
 ! SPLIT: hlfir.assign %[[RES]] to %[[X]]#0
 
 ! DEFAULT-LABEL: func.func @_QPeligible_scalar_term
@@ -236,7 +236,7 @@ subroutine eligible_scalar_term(x,a,b,c,d,e)
 ! DEFAULT: hlfir.assign %[[RES]] to %[[X]]#0
 
 ! Default:   (((x + (a-b)) + (c-d)) + (e-f))
-! Rewritten: ((c-d) + (e-f)) + (x + (a-b))
+! Rewritten: (x + (a-b)) + ((c-d) + (e-f))
 subroutine eligible_parenthesized_subtractions(x,a,b,c,d,e,f)
   real(8) :: x,a,b,c,d,e,f
   x = x + (a-b) + (c-d) + (e-f)
@@ -250,6 +250,12 @@ subroutine eligible_parenthesized_subtractions(x,a,b,c,d,e,f)
 ! SPLIT-DAG: %[[E:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_parenthesized_subtractionsEe"}
 ! SPLIT-DAG: %[[F:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_parenthesized_subtractionsEf"}
 ! SPLIT-DAG: %[[X:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_parenthesized_subtractionsEx"}
+! SPLIT: %[[XV:.*]] = fir.load %[[X]]#0
+! SPLIT: %[[AV:.*]] = fir.load %[[A]]#0
+! SPLIT: %[[BV:.*]] = fir.load %[[B]]#0
+! SPLIT: %[[AB_SUB:.*]] = arith.subf %[[AV]], %[[BV]]
+! SPLIT: %[[AB:.*]] = hlfir.no_reassoc %[[AB_SUB]]
+! SPLIT: %[[HEAD:.*]] = arith.addf %[[XV]], %[[AB]]
 ! SPLIT: %[[CV:.*]] = fir.load %[[C]]#0
 ! SPLIT: %[[DV:.*]] = fir.load %[[D]]#0
 ! SPLIT: %[[CD_SUB:.*]] = arith.subf %[[CV]], %[[DV]]
@@ -259,13 +265,7 @@ subroutine eligible_parenthesized_subtractions(x,a,b,c,d,e,f)
 ! SPLIT: %[[EF_SUB:.*]] = arith.subf %[[EV]], %[[FV]]
 ! SPLIT: %[[EF:.*]] = hlfir.no_reassoc %[[EF_SUB]]
 ! SPLIT: %[[TAIL:.*]] = arith.addf %[[CD]], %[[EF]]
-! SPLIT: %[[XV:.*]] = fir.load %[[X]]#0
-! SPLIT: %[[AV:.*]] = fir.load %[[A]]#0
-! SPLIT: %[[BV:.*]] = fir.load %[[B]]#0
-! SPLIT: %[[AB_SUB:.*]] = arith.subf %[[AV]], %[[BV]]
-! SPLIT: %[[AB:.*]] = hlfir.no_reassoc %[[AB_SUB]]
-! SPLIT: %[[HEAD:.*]] = arith.addf %[[XV]], %[[AB]]
-! SPLIT: %[[RES:.*]] = arith.addf %[[TAIL]], %[[HEAD]]
+! SPLIT: %[[RES:.*]] = arith.addf %[[HEAD]], %[[TAIL]]
 ! SPLIT: hlfir.assign %[[RES]] to %[[X]]#0
 
 ! DEFAULT-LABEL: func.func @_QPeligible_parenthesized_subtractions
@@ -297,7 +297,7 @@ subroutine eligible_parenthesized_subtractions(x,a,b,c,d,e,f)
 ! The parenthesized addition is moved as one opaque term; its inner Add is not
 ! part of the top-level additive spine.
 ! Default:   (((x + (a+b)) + c*d) + e*f)
-! Rewritten: ((c*d + e*f) + (x + (a+b)))
+! Rewritten: ((x + (a+b)) + (c*d + e*f))
 subroutine eligible_parenthesized_add(x,a,b,c,d,e,f)
   real(8) :: x,a,b,c,d,e,f
   x = x + (a+b) + c*d + e*f
@@ -311,6 +311,12 @@ subroutine eligible_parenthesized_add(x,a,b,c,d,e,f)
 ! SPLIT-DAG: %[[E:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_parenthesized_addEe"}
 ! SPLIT-DAG: %[[F:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_parenthesized_addEf"}
 ! SPLIT-DAG: %[[X:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_parenthesized_addEx"}
+! SPLIT: %[[XV:.*]] = fir.load %[[X]]#0
+! SPLIT: %[[AV:.*]] = fir.load %[[A]]#0
+! SPLIT: %[[BV:.*]] = fir.load %[[B]]#0
+! SPLIT: %[[AB_ADD:.*]] = arith.addf %[[AV]], %[[BV]]
+! SPLIT: %[[AB:.*]] = hlfir.no_reassoc %[[AB_ADD]]
+! SPLIT: %[[HEAD:.*]] = arith.addf %[[XV]], %[[AB]]
 ! SPLIT: %[[CV:.*]] = fir.load %[[C]]#0
 ! SPLIT: %[[DV:.*]] = fir.load %[[D]]#0
 ! SPLIT: %[[CD:.*]] = arith.mulf %[[CV]], %[[DV]]
@@ -318,13 +324,7 @@ subroutine eligible_parenthesized_add(x,a,b,c,d,e,f)
 ! SPLIT: %[[FV:.*]] = fir.load %[[F]]#0
 ! SPLIT: %[[EF:.*]] = arith.mulf %[[EV]], %[[FV]]
 ! SPLIT: %[[TAIL:.*]] = arith.addf %[[CD]], %[[EF]]
-! SPLIT: %[[XV:.*]] = fir.load %[[X]]#0
-! SPLIT: %[[AV:.*]] = fir.load %[[A]]#0
-! SPLIT: %[[BV:.*]] = fir.load %[[B]]#0
-! SPLIT: %[[AB_ADD:.*]] = arith.addf %[[AV]], %[[BV]]
-! SPLIT: %[[AB:.*]] = hlfir.no_reassoc %[[AB_ADD]]
-! SPLIT: %[[HEAD:.*]] = arith.addf %[[XV]], %[[AB]]
-! SPLIT: %[[RES:.*]] = arith.addf %[[TAIL]], %[[HEAD]]
+! SPLIT: %[[RES:.*]] = arith.addf %[[HEAD]], %[[TAIL]]
 ! SPLIT: hlfir.assign %[[RES]] to %[[X]]#0
 
 ! DEFAULT-LABEL: func.func @_QPeligible_parenthesized_add
@@ -386,7 +386,7 @@ subroutine guard_whole_rhs_parentheses(x,a,b,c,d,e,f)
 ! The unparenthesized Subtract is flattened into separate positive and negative
 ! terms instead of remaining an opaque head term.
 ! Default:   (((x - a*b) + c*d) + e*f)
-! Rewritten: (c*d + e*f) + (x - a*b)
+! Rewritten: (x - a*b) + (c*d + e*f)
 subroutine eligible_signed_subtract(x,a,b,c,d,e,f)
   real(8) :: x,a,b,c,d,e,f
   x = x - a*b + c*d + e*f
@@ -400,6 +400,11 @@ subroutine eligible_signed_subtract(x,a,b,c,d,e,f)
 ! SPLIT-DAG: %[[E:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_signed_subtractEe"}
 ! SPLIT-DAG: %[[F:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_signed_subtractEf"}
 ! SPLIT-DAG: %[[X:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_signed_subtractEx"}
+! SPLIT: %[[XV:.*]] = fir.load %[[X]]#0
+! SPLIT: %[[AV:.*]] = fir.load %[[A]]#0
+! SPLIT: %[[BV:.*]] = fir.load %[[B]]#0
+! SPLIT: %[[AB:.*]] = arith.mulf %[[AV]], %[[BV]]
+! SPLIT: %[[HEAD:.*]] = arith.subf %[[XV]], %[[AB]]
 ! SPLIT: %[[CV:.*]] = fir.load %[[C]]#0
 ! SPLIT: %[[DV:.*]] = fir.load %[[D]]#0
 ! SPLIT: %[[CD:.*]] = arith.mulf %[[CV]], %[[DV]]
@@ -407,12 +412,7 @@ subroutine eligible_signed_subtract(x,a,b,c,d,e,f)
 ! SPLIT: %[[FV:.*]] = fir.load %[[F]]#0
 ! SPLIT: %[[EF:.*]] = arith.mulf %[[EV]], %[[FV]]
 ! SPLIT: %[[TAIL:.*]] = arith.addf %[[CD]], %[[EF]]
-! SPLIT: %[[XV:.*]] = fir.load %[[X]]#0
-! SPLIT: %[[AV:.*]] = fir.load %[[A]]#0
-! SPLIT: %[[BV:.*]] = fir.load %[[B]]#0
-! SPLIT: %[[AB:.*]] = arith.mulf %[[AV]], %[[BV]]
-! SPLIT: %[[HEAD:.*]] = arith.subf %[[XV]], %[[AB]]
-! SPLIT: %[[RES:.*]] = arith.addf %[[TAIL]], %[[HEAD]]
+! SPLIT: %[[RES:.*]] = arith.addf %[[HEAD]], %[[TAIL]]
 ! SPLIT: hlfir.assign %[[RES]] to %[[X]]#0
 
 ! DEFAULT-LABEL: func.func @_QPeligible_signed_subtract
@@ -438,8 +438,8 @@ subroutine eligible_signed_subtract(x,a,b,c,d,e,f)
 ! DEFAULT: %[[RES:.*]] = arith.addf %[[XABCD]], %[[EF]]
 ! DEFAULT: hlfir.assign %[[RES]] to %[[X]]#0
 
-! The tail starts negative. Rebuild -b+c as -(b-c), then use the explicitly
-! permitted -X+Y -> Y-X reassociation to avoid a unary negation:
+! The tail starts negative. Rebuild -b+c as -(b-c), then subtract the
+! tail from the positive head without introducing a unary negation:
 ! Default:   (((x + a) - b) + c)
 ! Rewritten: (x + a) - (b - c)
 subroutine eligible_leading_negative_tail(x,a,b,c)
@@ -477,7 +477,7 @@ subroutine eligible_leading_negative_tail(x,a,b,c)
 
 ! The tail ends negative and can be rebuilt directly with Subtract.
 ! Default:   (((x + a) + b) - c)
-! Rewritten: (b - c) + (x + a)
+! Rewritten: (x + a) + (b - c)
 subroutine eligible_trailing_negative_tail(x,a,b,c)
   real(8) :: x,a,b,c
   x = x + a + b - c
@@ -488,13 +488,13 @@ subroutine eligible_trailing_negative_tail(x,a,b,c)
 ! SPLIT-DAG: %[[B:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_trailing_negative_tailEb"}
 ! SPLIT-DAG: %[[C:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_trailing_negative_tailEc"}
 ! SPLIT-DAG: %[[X:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_trailing_negative_tailEx"}
-! SPLIT: %[[BV:.*]] = fir.load %[[B]]#0
-! SPLIT: %[[CV:.*]] = fir.load %[[C]]#0
-! SPLIT: %[[TAIL:.*]] = arith.subf %[[BV]], %[[CV]]
 ! SPLIT: %[[XV:.*]] = fir.load %[[X]]#0
 ! SPLIT: %[[AV:.*]] = fir.load %[[A]]#0
 ! SPLIT: %[[HEAD:.*]] = arith.addf %[[XV]], %[[AV]]
-! SPLIT: %[[RES:.*]] = arith.addf %[[TAIL]], %[[HEAD]]
+! SPLIT: %[[BV:.*]] = fir.load %[[B]]#0
+! SPLIT: %[[CV:.*]] = fir.load %[[C]]#0
+! SPLIT: %[[TAIL:.*]] = arith.subf %[[BV]], %[[CV]]
+! SPLIT: %[[RES:.*]] = arith.addf %[[HEAD]], %[[TAIL]]
 ! SPLIT: hlfir.assign %[[RES]] to %[[X]]#0
 
 ! DEFAULT-LABEL: func.func @_QPeligible_trailing_negative_tail
@@ -550,7 +550,7 @@ subroutine eligible_consecutive_subtraction(x,a,b,c)
 
 ! Nested unparenthesized Add and Subtract nodes all contribute signed terms.
 ! Default:   ((((x - a) + b) - c) + d)
-! Rewritten: (b - (c - d)) + (x - a)
+! Rewritten: (x - a) + (b - (c - d))
 subroutine eligible_nested_unparenthesized_subtraction(x,a,b,c,d)
   real(8) :: x,a,b,c,d
   x = x - a + b - c + d
@@ -562,15 +562,15 @@ subroutine eligible_nested_unparenthesized_subtraction(x,a,b,c,d)
 ! SPLIT-DAG: %[[C:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_nested_unparenthesized_subtractionEc"}
 ! SPLIT-DAG: %[[D:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_nested_unparenthesized_subtractionEd"}
 ! SPLIT-DAG: %[[X:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_nested_unparenthesized_subtractionEx"}
+! SPLIT: %[[XV:.*]] = fir.load %[[X]]#0
+! SPLIT: %[[AV:.*]] = fir.load %[[A]]#0
+! SPLIT: %[[HEAD:.*]] = arith.subf %[[XV]], %[[AV]]
 ! SPLIT: %[[BV:.*]] = fir.load %[[B]]#0
 ! SPLIT: %[[CV:.*]] = fir.load %[[C]]#0
 ! SPLIT: %[[DV:.*]] = fir.load %[[D]]#0
 ! SPLIT: %[[CD:.*]] = arith.subf %[[CV]], %[[DV]]
 ! SPLIT: %[[TAIL:.*]] = arith.subf %[[BV]], %[[CD]]
-! SPLIT: %[[XV:.*]] = fir.load %[[X]]#0
-! SPLIT: %[[AV:.*]] = fir.load %[[A]]#0
-! SPLIT: %[[HEAD:.*]] = arith.subf %[[XV]], %[[AV]]
-! SPLIT: %[[RES:.*]] = arith.addf %[[TAIL]], %[[HEAD]]
+! SPLIT: %[[RES:.*]] = arith.addf %[[HEAD]], %[[TAIL]]
 ! SPLIT: hlfir.assign %[[RES]] to %[[X]]#0
 
 ! DEFAULT-LABEL: func.func @_QPeligible_nested_unparenthesized_subtraction
@@ -593,7 +593,7 @@ subroutine eligible_nested_unparenthesized_subtraction(x,a,b,c,d)
 ! Complex addition and subtraction use the same signed-term split. The
 ! parenthesized c-d remains one opaque no_reassoc value.
 ! Default:   (((x - a) + b) - (c-d))
-! Rewritten: (b - (c-d)) + (x - a)
+! Rewritten: (x - a) + (b - (c-d))
 subroutine eligible_complex_signed_parenthesized(x,a,b,c,d)
   complex(4) :: x,a,b,c,d
   x = x - a + b - (c-d)
@@ -605,16 +605,16 @@ subroutine eligible_complex_signed_parenthesized(x,a,b,c,d)
 ! SPLIT-DAG: %[[C:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_complex_signed_parenthesizedEc"}
 ! SPLIT-DAG: %[[D:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_complex_signed_parenthesizedEd"}
 ! SPLIT-DAG: %[[X:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_complex_signed_parenthesizedEx"}
+! SPLIT: %[[XV:.*]] = fir.load %[[X]]#0
+! SPLIT: %[[AV:.*]] = fir.load %[[A]]#0
+! SPLIT: %[[HEAD:.*]] = fir.subc %[[XV]], %[[AV]] {{.*}} : complex<f32>
 ! SPLIT: %[[BV:.*]] = fir.load %[[B]]#0
 ! SPLIT: %[[CV:.*]] = fir.load %[[C]]#0
 ! SPLIT: %[[DV:.*]] = fir.load %[[D]]#0
 ! SPLIT: %[[CD_SUB:.*]] = fir.subc %[[CV]], %[[DV]] {{.*}} : complex<f32>
 ! SPLIT: %[[CD:.*]] = hlfir.no_reassoc %[[CD_SUB]] : complex<f32>
 ! SPLIT: %[[TAIL:.*]] = fir.subc %[[BV]], %[[CD]] {{.*}} : complex<f32>
-! SPLIT: %[[XV:.*]] = fir.load %[[X]]#0
-! SPLIT: %[[AV:.*]] = fir.load %[[A]]#0
-! SPLIT: %[[HEAD:.*]] = fir.subc %[[XV]], %[[AV]] {{.*}} : complex<f32>
-! SPLIT: %[[RES:.*]] = fir.addc %[[TAIL]], %[[HEAD]] {{.*}} : complex<f32>
+! SPLIT: %[[RES:.*]] = fir.addc %[[HEAD]], %[[TAIL]] {{.*}} : complex<f32>
 ! SPLIT: hlfir.assign %[[RES]] to %[[X]]#0
 
 ! DEFAULT-LABEL: func.func @_QPeligible_complex_signed_parenthesized
@@ -637,7 +637,7 @@ subroutine eligible_complex_signed_parenthesized(x,a,b,c,d)
 
 ! A second complex kind exercises category dispatch independently of kind.
 ! Default:   (((x + a) + b) + c)
-! Rewritten: (b + c) + (x + a)
+! Rewritten: (x + a) + (b + c)
 subroutine eligible_complex_kind8(x,a,b,c)
   complex(8) :: x,a,b,c
   x = x + a + b + c
@@ -648,13 +648,13 @@ subroutine eligible_complex_kind8(x,a,b,c)
 ! SPLIT-DAG: %[[B:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_complex_kind8Eb"}
 ! SPLIT-DAG: %[[C:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_complex_kind8Ec"}
 ! SPLIT-DAG: %[[X:.*]]:2 = hlfir.declare {{.*}} {uniq_name = "_QFeligible_complex_kind8Ex"}
-! SPLIT: %[[BV:.*]] = fir.load %[[B]]#0
-! SPLIT: %[[CV:.*]] = fir.load %[[C]]#0
-! SPLIT: %[[TAIL:.*]] = fir.addc %[[BV]], %[[CV]] {{.*}} : complex<f64>
 ! SPLIT: %[[XV:.*]] = fir.load %[[X]]#0
 ! SPLIT: %[[AV:.*]] = fir.load ...
[truncated]

``````````

</details>


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


More information about the flang-commits mailing list