[clang] [flang] [flang] Enable FP sum reassociation by default (PR #218746)
Tom Eccles via cfe-commits
cfe-commits at lists.llvm.org
Sun Sep 6 11:24:17 PDT 2026
https://github.com/tblah updated https://github.com/llvm/llvm-project/pull/218746
>From 7aecd7d9509f98f68ce64390dcd6ee78bc24a4bf Mon Sep 17 00:00:00 2001
From: Tom Eccles <tom.eccles at arm.com>
Date: Tue, 25 Aug 2026 17:12:17 +0100
Subject: [PATCH 1/2] [flang] Enable FP sum reassociation by default
Enable Fortran-standard-compliant reassociation within individual
REAL and COMPLEX sum expressions by default at -O1 and above. Keep
left-to-right lowering at -O0 and preserve the explicit positive and
negative Flang override flags.
bbc uses -O2 by default, so enable the same lowering by default in bbc
with a boolean option.
Assisted-by: Codex
---
clang/include/clang/Options/FlangOptions.td | 6 ++++--
flang/docs/ReleaseNotes.md | 5 +++++
flang/lib/Frontend/CompilerInvocation.cpp | 3 ++-
flang/test/Driver/driver-help.f90 | 2 ++
flang/test/Lower/math-lowering/exponentiation.f90 | 6 +++---
flang/test/Lower/split-sum-expression-tree-lowering.f90 | 9 ++++++---
flang/tools/bbc/bbc.cpp | 7 +++++++
7 files changed, 29 insertions(+), 9 deletions(-)
diff --git a/clang/include/clang/Options/FlangOptions.td b/clang/include/clang/Options/FlangOptions.td
index 9dfe50593f33d..3e6cd0b8d9ea1 100644
--- a/clang/include/clang/Options/FlangOptions.td
+++ b/clang/include/clang/Options/FlangOptions.td
@@ -321,7 +321,8 @@ defm fp_sum_reassociation
PosFlag<SetTrue, [], [],
"Enable Fortran-standard compliant reassociation within "
"individual REAL and COMPLEX sum expressions. This may "
- "change exact floating-point results">,
+ "change exact floating-point results. Enabled by default "
+ "with -O1 and higher">,
NegFlag<SetFalse, [], [],
"Disable reassociation within individual REAL and COMPLEX "
"sum expressions">>,
@@ -329,7 +330,8 @@ defm fp_sum_reassociation
Enable Fortran-standard compliant reassociation within individual
``REAL`` and ``COMPLEX`` sum expressions. This can improve optimization
opportunities and may change exact floating-point results while
- preserving standard-conforming Fortran semantics.
+ preserving standard-conforming Fortran semantics. It is enabled by
+ default with ``-O1`` and higher.
}]>;
def freal_sum_reassociation : Flag<["-"], "freal-sum-reassociation">,
diff --git a/flang/docs/ReleaseNotes.md b/flang/docs/ReleaseNotes.md
index 0f5c1548f943d..bab1cfc722278 100644
--- a/flang/docs/ReleaseNotes.md
+++ b/flang/docs/ReleaseNotes.md
@@ -43,6 +43,11 @@ page](https://llvm.org/releases/).
as specified on the command line (except that ./foo.f90 removes the ./
prefix).
+- Fortran-standard-compliant reassociation within individual `REAL` and
+ `COMPLEX` sum expressions is now enabled by default at `-O1` and above.
+ This may change exact floating-point results. Flang users can restore
+ left-to-right evaluation with `-fno-fp-sum-reassociation`.
+
- The legacy array-value operations (`fir.array_load`, `fir.array_fetch`,
`fir.array_update`, `fir.array_modify`, `fir.array_access`,
`fir.array_amend`, `fir.array_merge_store`) have been removed from FIR,
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 7cfd89e120b7d..89d417a572c54 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -318,7 +318,8 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
opts.EnableSafeTrampoline = 1;
if (args.hasFlag(clang::options::OPT_ffp_sum_reassociation,
- clang::options::OPT_fno_fp_sum_reassociation, false))
+ clang::options::OPT_fno_fp_sum_reassociation,
+ opts.OptimizationLevel > 0))
opts.SplitSumExpressionTree = 1;
// Match the LLVM pipeline default (PipelineTuningOptions::LoopInterchange),
diff --git a/flang/test/Driver/driver-help.f90 b/flang/test/Driver/driver-help.f90
index 1ca446d159305..56843777aa2d0 100644
--- a/flang/test/Driver/driver-help.f90
+++ b/flang/test/Driver/driver-help.f90
@@ -10,6 +10,7 @@
! HELP: -ffp-sum-reassociation
! HELP: Enable Fortran-standard compliant reassociation within individual REAL and COMPLEX sum expressions
! HELP: may change exact floating-point results
+! HELP: Enabled by default with -O1 and higher
! HELP-NOT: -freal-sum-reassociation
! HELP-FC1:USAGE: flang
@@ -18,6 +19,7 @@
! HELP-FC1: -ffp-sum-reassociation
! HELP-FC1: Enable Fortran-standard compliant reassociation within individual REAL and COMPLEX sum expressions
! HELP-FC1: may change exact floating-point results
+! HELP-FC1: Enabled by default with -O1 and higher
! HELP-FC1-NOT: -freal-sum-reassociation
! ERROR: error: unknown argument '-helps'; did you mean '-help'
diff --git a/flang/test/Lower/math-lowering/exponentiation.f90 b/flang/test/Lower/math-lowering/exponentiation.f90
index 6a007d08671d6..4d3ebd10ef5e8 100644
--- a/flang/test/Lower/math-lowering/exponentiation.f90
+++ b/flang/test/Lower/math-lowering/exponentiation.f90
@@ -1,8 +1,8 @@
-! RUN: bbc -emit-fir %s -o - --math-runtime=fast | FileCheck --check-prefixes=ALL,FAST %s
+! RUN: bbc -emit-fir %s -o - --math-runtime=fast -ffp-sum-reassociation=false | FileCheck --check-prefixes=ALL,FAST %s
! RUN: %flang_fc1 -emit-fir -mllvm -math-runtime=fast %s -o - | FileCheck --check-prefixes=ALL,FAST %s
-! RUN: bbc -emit-fir %s -o - --math-runtime=relaxed | FileCheck --check-prefixes=ALL,RELAXED %s
+! RUN: bbc -emit-fir %s -o - --math-runtime=relaxed -ffp-sum-reassociation=false | FileCheck --check-prefixes=ALL,RELAXED %s
! RUN: %flang_fc1 -emit-fir -mllvm -math-runtime=relaxed %s -o - | FileCheck --check-prefixes=ALL,RELAXED %s
-! RUN: bbc -emit-fir %s -o - --math-runtime=precise | FileCheck --check-prefixes=ALL,PRECISE %s
+! RUN: bbc -emit-fir %s -o - --math-runtime=precise -ffp-sum-reassociation=false | FileCheck --check-prefixes=ALL,PRECISE %s
! RUN: %flang_fc1 -emit-fir -mllvm -math-runtime=precise %s -o - | FileCheck --check-prefixes=ALL,PRECISE %s
function test_real4(x, y, s, i, k)
diff --git a/flang/test/Lower/split-sum-expression-tree-lowering.f90 b/flang/test/Lower/split-sum-expression-tree-lowering.f90
index 4b9b49219d8b8..2da6c48e7326d 100644
--- a/flang/test/Lower/split-sum-expression-tree-lowering.f90
+++ b/flang/test/Lower/split-sum-expression-tree-lowering.f90
@@ -1,6 +1,9 @@
-! RUN: %flang_fc1 -emit-hlfir -ffp-sum-reassociation -o - %s | FileCheck %s --check-prefixes=SPLIT,NO-REWRITE --implicit-check-not=arith.negf
-! RUN: %flang_fc1 -emit-hlfir -fno-fp-sum-reassociation -o - %s | FileCheck %s --check-prefixes=DEFAULT,NO-REWRITE
-! RUN: %flang_fc1 -emit-hlfir -o - %s | FileCheck %s --check-prefixes=DEFAULT,NO-REWRITE
+! RUN: %flang_fc1 -emit-hlfir -O0 -o - %s | FileCheck %s --check-prefixes=DEFAULT,NO-REWRITE
+! RUN: %flang_fc1 -emit-hlfir -O1 -o - %s | FileCheck %s --check-prefixes=SPLIT,NO-REWRITE --implicit-check-not=arith.negf
+! RUN: %flang_fc1 -emit-hlfir -O0 -ffp-sum-reassociation -o - %s | FileCheck %s --check-prefixes=SPLIT,NO-REWRITE --implicit-check-not=arith.negf
+! RUN: %flang_fc1 -emit-hlfir -O1 -fno-fp-sum-reassociation -o - %s | FileCheck %s --check-prefixes=DEFAULT,NO-REWRITE
+! RUN: bbc -emit-hlfir -o - %s | FileCheck %s --check-prefixes=SPLIT,NO-REWRITE --implicit-check-not=arith.negf
+! 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))
diff --git a/flang/tools/bbc/bbc.cpp b/flang/tools/bbc/bbc.cpp
index 50742eb106421..d6e0643c813c2 100644
--- a/flang/tools/bbc/bbc.cpp
+++ b/flang/tools/bbc/bbc.cpp
@@ -282,6 +282,12 @@ static llvm::cl::opt<bool>
"the LHS of the intrinsic assignment"),
llvm::cl::init(true));
+static llvm::cl::opt<bool> fpSumReassociation(
+ "ffp-sum-reassociation",
+ llvm::cl::desc("Enable Fortran-standard compliant reassociation within "
+ "individual REAL and COMPLEX sum expressions"),
+ llvm::cl::init(true));
+
static llvm::cl::opt<bool> stackRepackArrays(
"fstack-repack-arrays",
llvm::cl::desc("Allocate temporary arrays for -frepack-arrays "
@@ -507,6 +513,7 @@ static llvm::LogicalResult convertFortranSourceToMLIR(
loweringOptions.setIntegerWrapAround(integerWrapAround);
loweringOptions.setInitGlobalZero(initGlobalZero);
loweringOptions.setReallocateLHS(reallocateLHS);
+ loweringOptions.setSplitSumExpressionTree(fpSumReassociation);
loweringOptions.setStackRepackArrays(stackRepackArrays);
loweringOptions.setRepackArrays(repackArrays);
loweringOptions.setRepackArraysWhole(repackArraysWhole);
>From 8ac7f8d53e8d9babcc2420b2cdb130d26418744d Mon Sep 17 00:00:00 2001
From: Tom Eccles <tom.eccles at arm.com>
Date: Sun, 6 Sep 2026 18:45:57 +0100
Subject: [PATCH 2/2] Enable FP sum reassociation at all optimization levels
I decided to do it at O0 after Jean's feedback on the RFC/Discourse.
Thinking more about it, in badly written programs this could
theoretically change program flow and so it would be very confusing if a
slightly different numerical result was given at -O0 (e.g. a debug
build) than -O3.
Assisted-by: Codex
---
clang/include/clang/Options/FlangOptions.td | 5 ++---
flang/docs/ReleaseNotes.md | 6 +++---
flang/lib/Frontend/CompilerInvocation.cpp | 3 +--
flang/test/Driver/driver-help.f90 | 4 ++--
flang/test/Lower/math-lowering/exponentiation.f90 | 6 +++---
flang/test/Lower/split-sum-expression-tree-lowering.f90 | 4 ++--
6 files changed, 13 insertions(+), 15 deletions(-)
diff --git a/clang/include/clang/Options/FlangOptions.td b/clang/include/clang/Options/FlangOptions.td
index 3e6cd0b8d9ea1..dad57464799c3 100644
--- a/clang/include/clang/Options/FlangOptions.td
+++ b/clang/include/clang/Options/FlangOptions.td
@@ -321,8 +321,7 @@ defm fp_sum_reassociation
PosFlag<SetTrue, [], [],
"Enable Fortran-standard compliant reassociation within "
"individual REAL and COMPLEX sum expressions. This may "
- "change exact floating-point results. Enabled by default "
- "with -O1 and higher">,
+ "change exact floating-point results. Enabled by default">,
NegFlag<SetFalse, [], [],
"Disable reassociation within individual REAL and COMPLEX "
"sum expressions">>,
@@ -331,7 +330,7 @@ defm fp_sum_reassociation
``REAL`` and ``COMPLEX`` sum expressions. This can improve optimization
opportunities and may change exact floating-point results while
preserving standard-conforming Fortran semantics. It is enabled by
- default with ``-O1`` and higher.
+ default at all optimization levels.
}]>;
def freal_sum_reassociation : Flag<["-"], "freal-sum-reassociation">,
diff --git a/flang/docs/ReleaseNotes.md b/flang/docs/ReleaseNotes.md
index bab1cfc722278..76a6b95dd3ecc 100644
--- a/flang/docs/ReleaseNotes.md
+++ b/flang/docs/ReleaseNotes.md
@@ -44,9 +44,9 @@ page](https://llvm.org/releases/).
prefix).
- Fortran-standard-compliant reassociation within individual `REAL` and
- `COMPLEX` sum expressions is now enabled by default at `-O1` and above.
- This may change exact floating-point results. Flang users can restore
- left-to-right evaluation with `-fno-fp-sum-reassociation`.
+ `COMPLEX` sum expressions is now enabled by default at all optimization
+ levels. This may change exact floating-point results. Flang users can
+ restore left-to-right evaluation with `-fno-fp-sum-reassociation`.
- The legacy array-value operations (`fir.array_load`, `fir.array_fetch`,
`fir.array_update`, `fir.array_modify`, `fir.array_access`,
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 89d417a572c54..b76b38ff6497f 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -318,8 +318,7 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
opts.EnableSafeTrampoline = 1;
if (args.hasFlag(clang::options::OPT_ffp_sum_reassociation,
- clang::options::OPT_fno_fp_sum_reassociation,
- opts.OptimizationLevel > 0))
+ clang::options::OPT_fno_fp_sum_reassociation, true))
opts.SplitSumExpressionTree = 1;
// Match the LLVM pipeline default (PipelineTuningOptions::LoopInterchange),
diff --git a/flang/test/Driver/driver-help.f90 b/flang/test/Driver/driver-help.f90
index 56843777aa2d0..ddffedac5d9f6 100644
--- a/flang/test/Driver/driver-help.f90
+++ b/flang/test/Driver/driver-help.f90
@@ -10,7 +10,7 @@
! HELP: -ffp-sum-reassociation
! HELP: Enable Fortran-standard compliant reassociation within individual REAL and COMPLEX sum expressions
! HELP: may change exact floating-point results
-! HELP: Enabled by default with -O1 and higher
+! HELP: Enabled by default
! HELP-NOT: -freal-sum-reassociation
! HELP-FC1:USAGE: flang
@@ -19,7 +19,7 @@
! HELP-FC1: -ffp-sum-reassociation
! HELP-FC1: Enable Fortran-standard compliant reassociation within individual REAL and COMPLEX sum expressions
! HELP-FC1: may change exact floating-point results
-! HELP-FC1: Enabled by default with -O1 and higher
+! HELP-FC1: Enabled by default
! HELP-FC1-NOT: -freal-sum-reassociation
! ERROR: error: unknown argument '-helps'; did you mean '-help'
diff --git a/flang/test/Lower/math-lowering/exponentiation.f90 b/flang/test/Lower/math-lowering/exponentiation.f90
index 4d3ebd10ef5e8..95cbfad7a83a8 100644
--- a/flang/test/Lower/math-lowering/exponentiation.f90
+++ b/flang/test/Lower/math-lowering/exponentiation.f90
@@ -1,9 +1,9 @@
! RUN: bbc -emit-fir %s -o - --math-runtime=fast -ffp-sum-reassociation=false | FileCheck --check-prefixes=ALL,FAST %s
-! RUN: %flang_fc1 -emit-fir -mllvm -math-runtime=fast %s -o - | FileCheck --check-prefixes=ALL,FAST %s
+! RUN: %flang_fc1 -emit-fir -fno-fp-sum-reassociation -mllvm -math-runtime=fast %s -o - | FileCheck --check-prefixes=ALL,FAST %s
! RUN: bbc -emit-fir %s -o - --math-runtime=relaxed -ffp-sum-reassociation=false | FileCheck --check-prefixes=ALL,RELAXED %s
-! RUN: %flang_fc1 -emit-fir -mllvm -math-runtime=relaxed %s -o - | FileCheck --check-prefixes=ALL,RELAXED %s
+! RUN: %flang_fc1 -emit-fir -fno-fp-sum-reassociation -mllvm -math-runtime=relaxed %s -o - | FileCheck --check-prefixes=ALL,RELAXED %s
! RUN: bbc -emit-fir %s -o - --math-runtime=precise -ffp-sum-reassociation=false | FileCheck --check-prefixes=ALL,PRECISE %s
-! RUN: %flang_fc1 -emit-fir -mllvm -math-runtime=precise %s -o - | FileCheck --check-prefixes=ALL,PRECISE %s
+! RUN: %flang_fc1 -emit-fir -fno-fp-sum-reassociation -mllvm -math-runtime=precise %s -o - | FileCheck --check-prefixes=ALL,PRECISE %s
function test_real4(x, y, s, i, k)
real :: x, y, test_real4
diff --git a/flang/test/Lower/split-sum-expression-tree-lowering.f90 b/flang/test/Lower/split-sum-expression-tree-lowering.f90
index 2da6c48e7326d..7d418d09cc319 100644
--- a/flang/test/Lower/split-sum-expression-tree-lowering.f90
+++ b/flang/test/Lower/split-sum-expression-tree-lowering.f90
@@ -1,6 +1,6 @@
-! RUN: %flang_fc1 -emit-hlfir -O0 -o - %s | FileCheck %s --check-prefixes=DEFAULT,NO-REWRITE
+! RUN: %flang_fc1 -emit-hlfir -O0 -o - %s | FileCheck %s --check-prefixes=SPLIT,NO-REWRITE --implicit-check-not=arith.negf
! RUN: %flang_fc1 -emit-hlfir -O1 -o - %s | FileCheck %s --check-prefixes=SPLIT,NO-REWRITE --implicit-check-not=arith.negf
-! RUN: %flang_fc1 -emit-hlfir -O0 -ffp-sum-reassociation -o - %s | FileCheck %s --check-prefixes=SPLIT,NO-REWRITE --implicit-check-not=arith.negf
+! RUN: %flang_fc1 -emit-hlfir -O0 -fno-fp-sum-reassociation -o - %s | FileCheck %s --check-prefixes=DEFAULT,NO-REWRITE
! RUN: %flang_fc1 -emit-hlfir -O1 -fno-fp-sum-reassociation -o - %s | FileCheck %s --check-prefixes=DEFAULT,NO-REWRITE
! RUN: bbc -emit-hlfir -o - %s | FileCheck %s --check-prefixes=SPLIT,NO-REWRITE --implicit-check-not=arith.negf
! RUN: bbc -emit-hlfir -ffp-sum-reassociation=false -o - %s | FileCheck %s --check-prefixes=DEFAULT,NO-REWRITE
More information about the cfe-commits
mailing list