[flang-commits] [flang] [flang] Join reassociated sums with the head first (PR #223966)
Tom Eccles via flang-commits
flang-commits at lists.llvm.org
Wed Sep 16 03:27:43 PDT 2026
https://github.com/tblah created https://github.com/llvm/llvm-project/pull/223966
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.
>From d0e835d43078ad75d23f0c5d3536e80e2298ff9b Mon Sep 17 00:00:00 2001
From: Tom Eccles <tom.eccles at arm.com>
Date: Tue, 15 Sep 2026 12:01:58 +0100
Subject: [PATCH] [flang] Join reassociated sums with the head first
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.
---
flang/lib/Evaluate/tools.cpp | 2 +-
flang/test/Lower/OpenACC/acc-cache.f90 | 2 +-
.../split-sum-expression-tree-lowering.f90 | 400 ++++++++++--------
.../split-sum-expression-tree-subscripts.f90 | 20 +-
4 files changed, 228 insertions(+), 196 deletions(-)
diff --git a/flang/lib/Evaluate/tools.cpp b/flang/lib/Evaluate/tools.cpp
index def85232cc572..f368335e82ddd 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 9bdacc17cd984..12bdee3833870 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 7d418d09cc319..8ffb5baae47db 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 %[[A]]#0
! SPLIT: %[[HEAD:.*]] = fir.addc %[[XV]], %[[AV]] {{.*}} : complex<f64>
-! SPLIT: %[[RES:.*]] = fir.addc %[[TAIL]], %[[HEAD]] {{.*}} : complex<f64>
+! SPLIT: %[[BV:.*]] = fir.load %[[B]]#0
+! SPLIT: %[[CV:.*]] = fir.load %[[C]]#0
+! SPLIT: %[[TAIL:.*]] = fir.addc %[[BV]], %[[CV]] {{.*}} : complex<f64>
+! SPLIT: %[[RES:.*]] = fir.addc %[[HEAD]], %[[TAIL]] {{.*}} : complex<f64>
! SPLIT: hlfir.assign %[[RES]] to %[[X]]#0
! It isn't as useful to re-write integer expressions because the middle-end can
@@ -754,7 +754,7 @@ subroutine guard_call(x,a,b,c,d,e)
! NO-REWRITE: hlfir.assign %[[RES]] to %[[X]]#0
! Default: (((x + sqrt((a+b)+c)) + d*e) + f*g)
-! Rewritten: ((d*e + f*g) + (x + sqrt((a+b)+c)))
+! Rewritten: ((x + sqrt((a+b)+c)) + (d*e + f*g))
! A qualifying outer sum is rewritten once. The pure call remains an opaque
! term, so its additive argument retains source order.
subroutine eligible_pure_call(x,a,b,c,d,e,f,g)
@@ -763,13 +763,6 @@ subroutine eligible_pure_call(x,a,b,c,d,e,f,g)
end
! SPLIT-LABEL: func.func @_QPeligible_pure_call
-! SPLIT: %[[DV:.*]] = fir.load
-! SPLIT: %[[EV:.*]] = fir.load
-! SPLIT: %[[DE:.*]] = arith.mulf %[[DV]], %[[EV]]
-! SPLIT: %[[FV:.*]] = fir.load
-! SPLIT: %[[GV:.*]] = fir.load
-! SPLIT: %[[FG:.*]] = arith.mulf %[[FV]], %[[GV]]
-! SPLIT: %[[TAIL:.*]] = arith.addf %[[DE]], %[[FG]]
! SPLIT: %[[XV:.*]] = fir.load
! SPLIT: %[[AV:.*]] = fir.load
! SPLIT: %[[BV:.*]] = fir.load
@@ -778,7 +771,14 @@ subroutine eligible_pure_call(x,a,b,c,d,e,f,g)
! SPLIT: %[[ABC:.*]] = arith.addf %[[AB]], %[[CV]]
! SPLIT: %[[CALL:.*]] = math.sqrt %[[ABC]]
! SPLIT: %[[HEAD:.*]] = arith.addf %[[XV]], %[[CALL]]
-! SPLIT: %[[RES:.*]] = arith.addf %[[TAIL]], %[[HEAD]]
+! SPLIT: %[[DV:.*]] = fir.load
+! SPLIT: %[[EV:.*]] = fir.load
+! SPLIT: %[[DE:.*]] = arith.mulf %[[DV]], %[[EV]]
+! SPLIT: %[[FV:.*]] = fir.load
+! SPLIT: %[[GV:.*]] = fir.load
+! SPLIT: %[[FG:.*]] = arith.mulf %[[FV]], %[[GV]]
+! SPLIT: %[[TAIL:.*]] = arith.addf %[[DE]], %[[FG]]
+! SPLIT: %[[RES:.*]] = arith.addf %[[HEAD]], %[[TAIL]]
! SPLIT: hlfir.assign %[[RES]]
! DEFAULT-LABEL: func.func @_QPeligible_pure_call
@@ -840,129 +840,149 @@ subroutine guard_nested_impure_call(x,a,b,c,d,e)
! NO-REWRITE: %[[RES:.*]] = arith.addf %[[HEAD_BC]], %[[DE]]
! NO-REWRITE: hlfir.assign %[[RES]]
-! Default: d * real((a+b)+c,8)
-! Rewritten: d * real(c+(a+b),8)
-subroutine nested_conversion_operand(x,a,b,c,d)
- real(8) :: x,d
- real(4) :: a,b,c
- x = d * real(a+b+c,8)
+! Default: e * real(((a+b)+c)+d,8)
+! Rewritten: e * real((a+b)+(c+d),8)
+subroutine nested_conversion_operand(x,a,b,c,d,e)
+ real(8) :: x,e
+ real(4) :: a,b,c,d
+ x = e * real(a+b+c+d,8)
end
! SPLIT-LABEL: func.func @_QPnested_conversion_operand
-! SPLIT: %[[DV:.*]] = fir.load
-! SPLIT: %[[CV:.*]] = fir.load
+! SPLIT: %[[EV:.*]] = fir.load
! SPLIT: %[[AV:.*]] = fir.load
! SPLIT: %[[BV:.*]] = fir.load
-! SPLIT: %[[AB:.*]] = arith.addf %[[AV]], %[[BV]]
-! SPLIT: %[[SUM:.*]] = arith.addf %[[CV]], %[[AB]]
-! SPLIT: %[[CONVERT:.*]] = fir.convert %[[SUM]]
-! SPLIT: %[[RES:.*]] = arith.mulf %[[DV]], %[[CONVERT]]
+! SPLIT: %[[S1:.*]] = arith.addf %[[AV]], %[[BV]]
+! SPLIT: %[[CV:.*]] = fir.load
+! SPLIT: %[[DV:.*]] = fir.load
+! SPLIT: %[[S2:.*]] = arith.addf %[[CV]], %[[DV]]
+! SPLIT: %[[S3:.*]] = arith.addf %[[S1]], %[[S2]]
+! SPLIT: %[[CONVERT:.*]] = fir.convert %[[S3]] : (f32) -> f64
+! SPLIT: %[[RES:.*]] = arith.mulf %[[EV]], %[[CONVERT]]
! SPLIT: hlfir.assign %[[RES]]
! DEFAULT-LABEL: func.func @_QPnested_conversion_operand
-! DEFAULT: %[[DV:.*]] = fir.load
+! DEFAULT: %[[EV:.*]] = fir.load
! DEFAULT: %[[AV:.*]] = fir.load
! DEFAULT: %[[BV:.*]] = fir.load
-! DEFAULT: %[[AB:.*]] = arith.addf %[[AV]], %[[BV]]
+! DEFAULT: %[[S1:.*]] = arith.addf %[[AV]], %[[BV]]
! DEFAULT: %[[CV:.*]] = fir.load
-! DEFAULT: %[[SUM:.*]] = arith.addf %[[AB]], %[[CV]]
-! DEFAULT: %[[CONVERT:.*]] = fir.convert %[[SUM]]
-! DEFAULT: %[[RES:.*]] = arith.mulf %[[DV]], %[[CONVERT]]
+! DEFAULT: %[[S2:.*]] = arith.addf %[[S1]], %[[CV]]
+! DEFAULT: %[[DV:.*]] = fir.load
+! DEFAULT: %[[S3:.*]] = arith.addf %[[S2]], %[[DV]]
+! DEFAULT: %[[CONVERT:.*]] = fir.convert %[[S3]] : (f32) -> f64
+! DEFAULT: %[[RES:.*]] = arith.mulf %[[EV]], %[[CONVERT]]
! DEFAULT: hlfir.assign %[[RES]]
-! Default: sqrt((a+b)+c)
-! Rewritten: sqrt(c+(a+b))
-subroutine nested_pure_call_argument(x,a,b,c)
- real(8) :: x,a,b,c
- x = sqrt(a+b+c)
+! Default: sqrt(((a+b)+c)+d)
+! Rewritten: sqrt((a+b)+(c+d))
+subroutine nested_pure_call_argument(x,a,b,c,d)
+ real(8) :: x,a,b,c,d
+ x = sqrt(a+b+c+d)
end
! SPLIT-LABEL: func.func @_QPnested_pure_call_argument
-! SPLIT: %[[CV:.*]] = fir.load
! SPLIT: %[[AV:.*]] = fir.load
! SPLIT: %[[BV:.*]] = fir.load
-! SPLIT: %[[AB:.*]] = arith.addf %[[AV]], %[[BV]]
-! SPLIT: %[[SUM:.*]] = arith.addf %[[CV]], %[[AB]]
-! SPLIT: %[[SQRT:.*]] = math.sqrt %[[SUM]]
+! SPLIT: %[[S1:.*]] = arith.addf %[[AV]], %[[BV]]
+! SPLIT: %[[CV:.*]] = fir.load
+! SPLIT: %[[DV:.*]] = fir.load
+! SPLIT: %[[S2:.*]] = arith.addf %[[CV]], %[[DV]]
+! SPLIT: %[[S3:.*]] = arith.addf %[[S1]], %[[S2]]
+! SPLIT: %[[SQRT:.*]] = math.sqrt %[[S3]]
! SPLIT: hlfir.assign %[[SQRT]]
! DEFAULT-LABEL: func.func @_QPnested_pure_call_argument
! DEFAULT: %[[AV:.*]] = fir.load
! DEFAULT: %[[BV:.*]] = fir.load
-! DEFAULT: %[[AB:.*]] = arith.addf %[[AV]], %[[BV]]
+! DEFAULT: %[[S1:.*]] = arith.addf %[[AV]], %[[BV]]
! DEFAULT: %[[CV:.*]] = fir.load
-! DEFAULT: %[[SUM:.*]] = arith.addf %[[AB]], %[[CV]]
-! DEFAULT: %[[SQRT:.*]] = math.sqrt %[[SUM]]
+! DEFAULT: %[[S2:.*]] = arith.addf %[[S1]], %[[CV]]
+! DEFAULT: %[[DV:.*]] = fir.load
+! DEFAULT: %[[S3:.*]] = arith.addf %[[S2]], %[[DV]]
+! DEFAULT: %[[SQRT:.*]] = math.sqrt %[[S3]]
! DEFAULT: hlfir.assign %[[SQRT]]
-! Default: atan2((a+b)+c,(d+e)+f)
-! Rewritten: atan2(c+(a+b),f+(d+e))
-subroutine nested_separate_call_arguments(x,a,b,c,d,e,f)
- real(8) :: x,a,b,c,d,e,f
- x = atan2(a+b+c,d+e+f)
+! Default: atan2(((a+b)+c)+d,((e+f)+g)+h)
+! Rewritten: atan2((a+b)+(c+d),(e+f)+(g+h))
+subroutine nested_separate_call_arguments(x,a,b,c,d,e,f,g,h)
+ real(8) :: x,a,b,c,d,e,f,g,h
+ x = atan2(a+b+c+d,e+f+g+h)
end
! SPLIT-LABEL: func.func @_QPnested_separate_call_arguments
-! SPLIT: %[[CV:.*]] = fir.load
! SPLIT: %[[AV:.*]] = fir.load
! SPLIT: %[[BV:.*]] = fir.load
-! SPLIT: %[[AB:.*]] = arith.addf %[[AV]], %[[BV]]
-! SPLIT: %[[FIRST:.*]] = arith.addf %[[CV]], %[[AB]]
-! SPLIT: %[[FV:.*]] = fir.load
+! SPLIT: %[[S1:.*]] = arith.addf %[[AV]], %[[BV]]
+! SPLIT: %[[CV:.*]] = fir.load
! SPLIT: %[[DV:.*]] = fir.load
+! SPLIT: %[[S2:.*]] = arith.addf %[[CV]], %[[DV]]
+! SPLIT: %[[S3:.*]] = arith.addf %[[S1]], %[[S2]]
! SPLIT: %[[EV:.*]] = fir.load
-! SPLIT: %[[DE:.*]] = arith.addf %[[DV]], %[[EV]]
-! SPLIT: %[[SECOND:.*]] = arith.addf %[[FV]], %[[DE]]
-! SPLIT: math.atan2 %[[FIRST]], %[[SECOND]]
-
-! Default: (flag ? (a+b)+c : d)
-! Rewritten: (flag ? c+(a+b) : d)
-subroutine nested_conditional_branch(x,flag,a,b,c,d)
- real(8) :: x,a,b,c,d
+! SPLIT: %[[FV:.*]] = fir.load
+! SPLIT: %[[S4:.*]] = arith.addf %[[EV]], %[[FV]]
+! SPLIT: %[[GV:.*]] = fir.load
+! SPLIT: %[[HV:.*]] = fir.load
+! SPLIT: %[[S5:.*]] = arith.addf %[[GV]], %[[HV]]
+! SPLIT: %[[S6:.*]] = arith.addf %[[S4]], %[[S5]]
+! SPLIT: math.atan2 %[[S3]], %[[S6]]
+
+! Default: (flag ? (((a+b)+c)+d) : e)
+! Rewritten: (flag ? ((a+b)+(c+d)) : e)
+subroutine nested_conditional_branch(x,flag,a,b,c,d,e)
+ real(8) :: x,a,b,c,d,e
logical :: flag
- x = (flag ? a+b+c : d)
+ x = (flag ? a+b+c+d : e)
end
! SPLIT-LABEL: func.func @_QPnested_conditional_branch
! SPLIT: fir.if
-! SPLIT: %[[CV:.*]] = fir.load
! SPLIT: %[[AV:.*]] = fir.load
! SPLIT: %[[BV:.*]] = fir.load
-! SPLIT: %[[AB:.*]] = arith.addf %[[AV]], %[[BV]]
-! SPLIT: %[[SUM:.*]] = arith.addf %[[CV]], %[[AB]]
-! SPLIT: fir.result %[[SUM]]
+! SPLIT: %[[S1:.*]] = arith.addf %[[AV]], %[[BV]]
+! SPLIT: %[[CV:.*]] = fir.load
+! SPLIT: %[[DV:.*]] = fir.load
+! SPLIT: %[[S2:.*]] = arith.addf %[[CV]], %[[DV]]
+! SPLIT: %[[S3:.*]] = arith.addf %[[S1]], %[[S2]]
+! SPLIT: fir.result %[[S3]]
! DEFAULT-LABEL: func.func @_QPnested_conditional_branch
! DEFAULT: fir.if
! DEFAULT: %[[AV:.*]] = fir.load
! DEFAULT: %[[BV:.*]] = fir.load
-! DEFAULT: %[[AB:.*]] = arith.addf %[[AV]], %[[BV]]
+! DEFAULT: %[[S1:.*]] = arith.addf %[[AV]], %[[BV]]
! DEFAULT: %[[CV:.*]] = fir.load
-! DEFAULT: %[[SUM:.*]] = arith.addf %[[AB]], %[[CV]]
-! DEFAULT: fir.result %[[SUM]]
+! DEFAULT: %[[S2:.*]] = arith.addf %[[S1]], %[[CV]]
+! DEFAULT: %[[DV:.*]] = fir.load
+! DEFAULT: %[[S3:.*]] = arith.addf %[[S2]], %[[DV]]
+! DEFAULT: fir.result %[[S3]]
-! Default: ((a+b)+c > d ? e : f)
-! Rewritten: (c+(a+b) > d ? e : f)
-subroutine nested_relational_operand(x,a,b,c,d,e,f)
- real(8) :: x,a,b,c,d,e,f
- x = (a+b+c > d ? e : f)
+! Default: (((a+b)+c)+d > e ? f : g)
+! Rewritten: ((a+b)+(c+d) > e ? f : g)
+subroutine nested_relational_operand(x,a,b,c,d,e,f,g)
+ real(8) :: x,a,b,c,d,e,f,g
+ x = (a+b+c+d > e ? f : g)
end
! SPLIT-LABEL: func.func @_QPnested_relational_operand
-! SPLIT: %[[CV:.*]] = fir.load
! SPLIT: %[[AV:.*]] = fir.load
! SPLIT: %[[BV:.*]] = fir.load
-! SPLIT: %[[AB:.*]] = arith.addf %[[AV]], %[[BV]]
-! SPLIT: %[[SUM:.*]] = arith.addf %[[CV]], %[[AB]]
-! SPLIT: arith.cmpf ogt, %[[SUM]]
+! SPLIT: %[[S1:.*]] = arith.addf %[[AV]], %[[BV]]
+! SPLIT: %[[CV:.*]] = fir.load
+! SPLIT: %[[DV:.*]] = fir.load
+! SPLIT: %[[S2:.*]] = arith.addf %[[CV]], %[[DV]]
+! SPLIT: %[[S3:.*]] = arith.addf %[[S1]], %[[S2]]
+! SPLIT: arith.cmpf ogt, %[[S3]]
! DEFAULT-LABEL: func.func @_QPnested_relational_operand
! DEFAULT: %[[AV:.*]] = fir.load
! DEFAULT: %[[BV:.*]] = fir.load
-! DEFAULT: %[[AB:.*]] = arith.addf %[[AV]], %[[BV]]
+! DEFAULT: %[[S1:.*]] = arith.addf %[[AV]], %[[BV]]
! DEFAULT: %[[CV:.*]] = fir.load
-! DEFAULT: %[[SUM:.*]] = arith.addf %[[AB]], %[[CV]]
-! DEFAULT: arith.cmpf ogt, %[[SUM]]
+! DEFAULT: %[[S2:.*]] = arith.addf %[[S1]], %[[CV]]
+! DEFAULT: %[[DV:.*]] = fir.load
+! DEFAULT: %[[S3:.*]] = arith.addf %[[S2]], %[[DV]]
+! DEFAULT: arith.cmpf ogt, %[[S3]]
subroutine guard_parenthesized_call_argument(x,a,b,c)
real(8) :: x,a,b,c
@@ -1068,69 +1088,81 @@ subroutine guard_short_sum(x,a,b)
! NO-REWRITE: hlfir.assign %[[RES]] to %[[X]]#0
! The kind conversion remains around the reassociated expression.
-! Default: ((a*b + c*d) + e*f)
-! Rewritten: (e*f + (a*b + c*d))
-subroutine eligible_whole_real_kind_conversion(x,a,b,c,d,e,f)
+! Default: (((a*b + c*d) + e*f) + g*h)
+! Rewritten: ((a*b + c*d) + (e*f + g*h))
+subroutine eligible_whole_real_kind_conversion(x,a,b,c,d,e,f,g,h)
real(8) :: x
- real(4) :: a,b,c,d,e,f
- x = a*b + c*d + e*f
+ real(4) :: a,b,c,d,e,f,g,h
+ x = a*b + c*d + e*f + g*h
end
! SPLIT-LABEL: func.func @_QPeligible_whole_real_kind_conversion
-! SPLIT: %[[EV:.*]] = fir.load
-! SPLIT: %[[FV:.*]] = fir.load
-! SPLIT: %[[EF:.*]] = arith.mulf %[[EV]], %[[FV]]
! SPLIT: %[[AV:.*]] = fir.load
! SPLIT: %[[BV:.*]] = fir.load
-! SPLIT: %[[AB:.*]] = arith.mulf %[[AV]], %[[BV]]
+! SPLIT: %[[S1:.*]] = arith.mulf %[[AV]], %[[BV]]
! SPLIT: %[[CV:.*]] = fir.load
! SPLIT: %[[DV:.*]] = fir.load
-! SPLIT: %[[CD:.*]] = arith.mulf %[[CV]], %[[DV]]
-! SPLIT: %[[HEAD:.*]] = arith.addf %[[AB]], %[[CD]]
-! SPLIT: %[[SUM:.*]] = arith.addf %[[EF]], %[[HEAD]]
-! SPLIT: %[[RES:.*]] = fir.convert %[[SUM]] : (f32) -> f64
-! SPLIT: hlfir.assign %[[RES]]
+! SPLIT: %[[S2:.*]] = arith.mulf %[[CV]], %[[DV]]
+! SPLIT: %[[S3:.*]] = arith.addf %[[S1]], %[[S2]]
+! SPLIT: %[[EV:.*]] = fir.load
+! SPLIT: %[[FV:.*]] = fir.load
+! SPLIT: %[[S4:.*]] = arith.mulf %[[EV]], %[[FV]]
+! SPLIT: %[[GV:.*]] = fir.load
+! SPLIT: %[[HV:.*]] = fir.load
+! SPLIT: %[[S5:.*]] = arith.mulf %[[GV]], %[[HV]]
+! SPLIT: %[[S6:.*]] = arith.addf %[[S4]], %[[S5]]
+! SPLIT: %[[S7:.*]] = arith.addf %[[S3]], %[[S6]]
+! SPLIT: %[[CONVERT:.*]] = fir.convert %[[S7]] : (f32) -> f64
+! SPLIT: hlfir.assign %[[CONVERT]]
! DEFAULT-LABEL: func.func @_QPeligible_whole_real_kind_conversion
! DEFAULT: %[[AV:.*]] = fir.load
! DEFAULT: %[[BV:.*]] = fir.load
-! DEFAULT: %[[AB:.*]] = arith.mulf %[[AV]], %[[BV]]
+! DEFAULT: %[[S1:.*]] = arith.mulf %[[AV]], %[[BV]]
! DEFAULT: %[[CV:.*]] = fir.load
! DEFAULT: %[[DV:.*]] = fir.load
-! DEFAULT: %[[CD:.*]] = arith.mulf %[[CV]], %[[DV]]
-! DEFAULT: %[[HEAD:.*]] = arith.addf %[[AB]], %[[CD]]
+! DEFAULT: %[[S2:.*]] = arith.mulf %[[CV]], %[[DV]]
+! DEFAULT: %[[S3:.*]] = arith.addf %[[S1]], %[[S2]]
! DEFAULT: %[[EV:.*]] = fir.load
! DEFAULT: %[[FV:.*]] = fir.load
-! DEFAULT: %[[EF:.*]] = arith.mulf %[[EV]], %[[FV]]
-! DEFAULT: %[[SUM:.*]] = arith.addf %[[HEAD]], %[[EF]]
-! DEFAULT: %[[RES:.*]] = fir.convert %[[SUM]] : (f32) -> f64
-! DEFAULT: hlfir.assign %[[RES]]
-
-! Default: ((a + b) + c)
-! Rewritten: (c + (a + b))
-subroutine eligible_whole_complex_kind_conversion(x,a,b,c)
+! DEFAULT: %[[S4:.*]] = arith.mulf %[[EV]], %[[FV]]
+! DEFAULT: %[[S5:.*]] = arith.addf %[[S3]], %[[S4]]
+! DEFAULT: %[[GV:.*]] = fir.load
+! DEFAULT: %[[HV:.*]] = fir.load
+! DEFAULT: %[[S6:.*]] = arith.mulf %[[GV]], %[[HV]]
+! DEFAULT: %[[S7:.*]] = arith.addf %[[S5]], %[[S6]]
+! DEFAULT: %[[CONVERT:.*]] = fir.convert %[[S7]] : (f32) -> f64
+! DEFAULT: hlfir.assign %[[CONVERT]]
+
+! Default: (((a + b) + c) + d)
+! Rewritten: ((a + b) + (c + d))
+subroutine eligible_whole_complex_kind_conversion(x,a,b,c,d)
complex(8) :: x
- complex(4) :: a,b,c
- x = a + b + c
+ complex(4) :: a,b,c,d
+ x = a + b + c + d
end
! SPLIT-LABEL: func.func @_QPeligible_whole_complex_kind_conversion
-! SPLIT: %[[CV:.*]] = fir.load
! SPLIT: %[[AV:.*]] = fir.load
! SPLIT: %[[BV:.*]] = fir.load
-! SPLIT: %[[HEAD:.*]] = fir.addc %[[AV]], %[[BV]]
-! SPLIT: %[[SUM:.*]] = fir.addc %[[CV]], %[[HEAD]]
-! SPLIT: %[[RES:.*]] = fir.convert %[[SUM]] : (complex<f32>) -> complex<f64>
-! SPLIT: hlfir.assign %[[RES]]
+! SPLIT: %[[S1:.*]] = fir.addc %[[AV]], %[[BV]]
+! SPLIT: %[[CV:.*]] = fir.load
+! SPLIT: %[[DV:.*]] = fir.load
+! SPLIT: %[[S2:.*]] = fir.addc %[[CV]], %[[DV]]
+! SPLIT: %[[S3:.*]] = fir.addc %[[S1]], %[[S2]]
+! SPLIT: %[[CONVERT:.*]] = fir.convert %[[S3]] : (complex<f32>) -> complex<f64>
+! SPLIT: hlfir.assign %[[CONVERT]]
! DEFAULT-LABEL: func.func @_QPeligible_whole_complex_kind_conversion
! DEFAULT: %[[AV:.*]] = fir.load
! DEFAULT: %[[BV:.*]] = fir.load
-! DEFAULT: %[[HEAD:.*]] = fir.addc %[[AV]], %[[BV]]
+! DEFAULT: %[[S1:.*]] = fir.addc %[[AV]], %[[BV]]
! DEFAULT: %[[CV:.*]] = fir.load
-! DEFAULT: %[[SUM:.*]] = fir.addc %[[HEAD]], %[[CV]]
-! DEFAULT: %[[RES:.*]] = fir.convert %[[SUM]] : (complex<f32>) -> complex<f64>
-! DEFAULT: hlfir.assign %[[RES]]
+! DEFAULT: %[[S2:.*]] = fir.addc %[[S1]], %[[CV]]
+! DEFAULT: %[[DV:.*]] = fir.load
+! DEFAULT: %[[S3:.*]] = fir.addc %[[S2]], %[[DV]]
+! DEFAULT: %[[CONVERT:.*]] = fir.convert %[[S3]] : (complex<f32>) -> complex<f64>
+! DEFAULT: hlfir.assign %[[CONVERT]]
! A conversion embedded in the additive tree is not yet eligible.
subroutine guard_embedded_kind_conversion(x,a,b,c,d,e,f)
diff --git a/flang/test/Lower/split-sum-expression-tree-subscripts.f90 b/flang/test/Lower/split-sum-expression-tree-subscripts.f90
index aac09e4443465..6b4953316a001 100644
--- a/flang/test/Lower/split-sum-expression-tree-subscripts.f90
+++ b/flang/test/Lower/split-sum-expression-tree-subscripts.f90
@@ -14,12 +14,12 @@ subroutine array_elements(i,x,a,b,c,d,e,f)
end
! SPLIT-LABEL: func.func @_QParray_elements
+! SPLIT: %[[AB:.*]] = arith.mulf
+! SPLIT: %[[HEAD:.*]] = arith.addf %{{.*}}, %[[AB]]
! SPLIT: %[[CD:.*]] = arith.mulf
! SPLIT: %[[EF:.*]] = arith.mulf
! SPLIT: %[[TAIL:.*]] = arith.addf %[[CD]], %[[EF]]
-! SPLIT: %[[AB:.*]] = arith.mulf
-! SPLIT: %[[HEAD:.*]] = arith.addf %{{.*}}, %[[AB]]
-! SPLIT: %[[SUM:.*]] = arith.addf %[[TAIL]], %[[HEAD]]
+! SPLIT: %[[SUM:.*]] = arith.addf %[[HEAD]], %[[TAIL]]
! SPLIT: hlfir.assign %[[SUM]]
! ORDERED-LABEL: func.func @_QParray_elements
@@ -39,12 +39,12 @@ subroutine nested_subscript(i,j,x,a,b,c,d,e,f)
end
! SPLIT-LABEL: func.func @_QPnested_subscript
+! SPLIT: %[[AB:.*]] = arith.mulf
+! SPLIT: %[[HEAD:.*]] = arith.addf %{{.*}}, %[[AB]]
! SPLIT: %[[CD:.*]] = arith.mulf
! SPLIT: %[[EF:.*]] = arith.mulf
! SPLIT: %[[TAIL:.*]] = arith.addf %[[CD]], %[[EF]]
-! SPLIT: %[[AB:.*]] = arith.mulf
-! SPLIT: %[[HEAD:.*]] = arith.addf %{{.*}}, %[[AB]]
-! SPLIT: %[[SUM:.*]] = arith.addf %[[TAIL]], %[[HEAD]]
+! SPLIT: %[[SUM:.*]] = arith.addf %[[HEAD]], %[[TAIL]]
! SPLIT: hlfir.assign %[[SUM]]
! ORDERED-LABEL: func.func @_QPnested_subscript
@@ -64,13 +64,13 @@ subroutine real_subscript_conversion(r,x,a,b,c,d,e,f)
end
! SPLIT-LABEL: func.func @_QPreal_subscript_conversion
-! SPLIT: %[[CD:.*]] = arith.mulf
-! SPLIT: %[[EF:.*]] = arith.mulf
-! SPLIT: %[[TAIL:.*]] = arith.addf %[[CD]], %[[EF]]
! SPLIT: fir.convert %{{.*}} : (f32) -> i64
! SPLIT: %[[AB:.*]] = arith.mulf
! SPLIT: %[[HEAD:.*]] = arith.addf %{{.*}}, %[[AB]]
-! SPLIT: %[[SUM:.*]] = arith.addf %[[TAIL]], %[[HEAD]]
+! SPLIT: %[[CD:.*]] = arith.mulf
+! SPLIT: %[[EF:.*]] = arith.mulf
+! SPLIT: %[[TAIL:.*]] = arith.addf %[[CD]], %[[EF]]
+! SPLIT: %[[SUM:.*]] = arith.addf %[[HEAD]], %[[TAIL]]
! SPLIT: hlfir.assign %[[SUM]]
! ORDERED-LABEL: func.func @_QPreal_subscript_conversion
More information about the flang-commits
mailing list