[llvm-branch-commits] [clang] [flang] [flang][Driver] Add option for real sum reassociation (PR #207377)
Tom Eccles via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Jul 7 08:34:28 PDT 2026
https://github.com/tblah updated https://github.com/llvm/llvm-project/pull/207377
>From f16abd7f9c90e59f315ba966fa76554150844411 Mon Sep 17 00:00:00 2001
From: Tom Eccles <tom.eccles at arm.com>
Date: Fri, 3 Jul 2026 12:11:47 +0100
Subject: [PATCH 1/2] [flang][Driver] Add option for real sum reassociation
Compiler driver option for #207371: -freal-sum-reassociation. This is in
the hidden help for now. Disabled by default.
Assisted-by: Codex
---
clang/include/clang/Options/FlangOptions.td | 9 +++++++++
clang/lib/Driver/ToolChains/Flang.cpp | 2 ++
flang/include/flang/Frontend/CodeGenOptions.def | 1 +
flang/include/flang/Lower/LoweringOptions.def | 4 ++++
flang/lib/Frontend/CompilerInvocation.cpp | 5 +++++
flang/lib/Lower/ConvertExprToHLFIR.cpp | 7 +------
flang/test/Driver/frontend-forwarding.f90 | 2 ++
flang/test/Lower/split-sum-expression-tree-lowering.f90 | 3 ++-
8 files changed, 26 insertions(+), 7 deletions(-)
diff --git a/clang/include/clang/Options/FlangOptions.td b/clang/include/clang/Options/FlangOptions.td
index 18242a465341b..d2b2a03e9eb9b 100644
--- a/clang/include/clang/Options/FlangOptions.td
+++ b/clang/include/clang/Options/FlangOptions.td
@@ -310,6 +310,15 @@ def ffast_real_mod : Flag<["-"], "ffast-real-mod">, Group<f_Group>,
def fno_fast_real_mod : Flag<["-"], "fno-fast-real-mod">, Group<f_Group>,
HelpText<"Disable optimization of MOD for REAL types in presence of -ffast-math">;
+defm real_sum_reassociation
+ : BoolOptionWithoutMarshalling<
+ "f", "real-sum-reassociation",
+ PosFlag<SetTrue, [HelpHidden], [],
+ "Enable Fortran-standard compliant reassociation within "
+ "individual REAL sum expressions">,
+ NegFlag<SetFalse, [HelpHidden], [],
+ "Disable reassociation within individual REAL sum expressions">>;
+
defm init_global_zero : BoolOptionWithoutMarshalling<"f", "init-global-zero",
PosFlag<SetTrue, [], [], "Zero initialize globals without default initialization (default)">,
NegFlag<SetFalse, [], [], "Do not zero initialize globals without default initialization">>;
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index ee67c570fb96c..28ed52fba49cc 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -240,6 +240,8 @@ void Flang::addCodegenOptions(const ArgList &Args,
Args.addOptInFlag(CmdArgs, options::OPT_fexperimental_loop_fusion,
options::OPT_fno_experimental_loop_fusion);
+ Args.addOptInFlag(CmdArgs, options::OPT_freal_sum_reassociation,
+ options::OPT_fno_real_sum_reassociation);
handleInterchangeLoopsArgs(Args, CmdArgs);
handleVectorizeLoopsArgs(Args, CmdArgs);
diff --git a/flang/include/flang/Frontend/CodeGenOptions.def b/flang/include/flang/Frontend/CodeGenOptions.def
index a5907b6edbd97..53ddc20a6e810 100644
--- a/flang/include/flang/Frontend/CodeGenOptions.def
+++ b/flang/include/flang/Frontend/CodeGenOptions.def
@@ -54,6 +54,7 @@ CODEGENOPT(VectorizeSLP, 1, 0) ///< Enable SLP vectorization.
CODEGENOPT(InterchangeLoops, 1, 0) ///< Enable loop interchange.
CODEGENOPT(FuseLoops, 1, 0) ///< Enable loop fusion.
CODEGENOPT(LoopVersioning, 1, 0) ///< Enable loop versioning.
+CODEGENOPT(SplitSumExpressionTree, 1, 0) ///< Split REAL addition expression trees.
CODEGENOPT(UnrollLoops, 1, 0) ///< Enable loop unrolling
CODEGENOPT(AliasAnalysis, 1, 0) ///< Enable alias analysis pass
CODEGENOPT(DwarfVersion, 3, 0) ///< Dwarf version
diff --git a/flang/include/flang/Lower/LoweringOptions.def b/flang/include/flang/Lower/LoweringOptions.def
index e89ad75704609..0b02ffd5a3b22 100644
--- a/flang/include/flang/Lower/LoweringOptions.def
+++ b/flang/include/flang/Lower/LoweringOptions.def
@@ -35,6 +35,10 @@ ENUM_LOWERINGOPT(Underscoring, unsigned, 1, 1)
/// On by default.
ENUM_LOWERINGOPT(ProtectParens, unsigned, 1, 1)
+/// If true, split REAL addition expression trees.
+/// Off by default.
+ENUM_LOWERINGOPT(SplitSumExpressionTree, unsigned, 1, 0)
+
/// If true, assume the behavior of integer overflow is defined
/// (i.e. wraps around as two's complement). Off by default.
ENUM_LOWERINGOPT(IntegerWrapAround, unsigned, 1, 0)
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 8e13fc9f05324..b5d6d56825622 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -300,6 +300,10 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
clang::options::OPT_fno_safe_trampoline, false))
opts.EnableSafeTrampoline = 1;
+ if (args.hasFlag(clang::options::OPT_freal_sum_reassociation,
+ clang::options::OPT_fno_real_sum_reassociation, false))
+ opts.SplitSumExpressionTree = 1;
+
if (args.getLastArg(clang::options::OPT_floop_interchange))
opts.InterchangeLoops = 1;
@@ -2001,6 +2005,7 @@ void CompilerInvocation::setLoweringOptions() {
loweringOpts.setIntegerWrapAround(langOptions.getSignedOverflowBehavior() ==
Fortran::common::LangOptions::SOB_Defined);
loweringOpts.setProtectParens(codegenOpts.ProtectParens);
+ loweringOpts.setSplitSumExpressionTree(codegenOpts.SplitSumExpressionTree);
Fortran::common::MathOptionsBase &mathOpts = loweringOpts.getMathOptions();
// TODO: when LangOptions are finalized, we can represent
// the math related options using Fortran::commmon::MathOptionsBase,
diff --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp
index 86380c1a8ad7e..e5e1ef1f8a5ac 100644
--- a/flang/lib/Lower/ConvertExprToHLFIR.cpp
+++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp
@@ -35,15 +35,10 @@
#include "mlir/IR/IRMapping.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/TypeSwitch.h"
-#include "llvm/Support/CommandLine.h"
#include <optional>
namespace {
-static llvm::cl::opt<bool> enableSplitSumExpressionTreeLowering(
- "enable-split-sum-expression-tree-lowering", llvm::cl::Hidden,
- llvm::cl::desc("Enable experimental split sum expression tree lowering"));
-
// This was modelled after isParenthesizedVariable()
template <typename T>
static bool isParenthesized(const Fortran::evaluate::Expr<T> &expr) {
@@ -2430,7 +2425,7 @@ hlfir::EntityWithAttributes Fortran::lower::convertAssignmentRhsToHLFIR(
mlir::Location loc, Fortran::lower::AbstractConverter &converter,
const Fortran::lower::SomeExpr &lhs, const Fortran::lower::SomeExpr &rhs,
Fortran::lower::SymMap &symMap, Fortran::lower::StatementContext &stmtCtx) {
- if (enableSplitSumExpressionTreeLowering &&
+ if (converter.getLoweringOptions().getSplitSumExpressionTree() &&
canBuildSplitSumExpressionTree(lhs, rhs))
if (std::optional<Fortran::lower::SomeExpr> rewritten =
tryBuildSplitSumExpressionTree(lhs, rhs))
diff --git a/flang/test/Driver/frontend-forwarding.f90 b/flang/test/Driver/frontend-forwarding.f90
index 2cc5524d351ff..63982f9bdcb9c 100644
--- a/flang/test/Driver/frontend-forwarding.f90
+++ b/flang/test/Driver/frontend-forwarding.f90
@@ -20,6 +20,7 @@
! RUN: -fomit-frame-pointer \
! RUN: -fpass-plugin=Bye%pluginext \
! RUN: -fversion-loops-for-stride \
+! RUN: -freal-sum-reassociation \
! RUN: -fno-ppc-native-vector-element-order \
! RUN: -fppc-native-vector-element-order \
! RUN: -mllvm -print-before-all \
@@ -50,6 +51,7 @@
! CHECK: "-freciprocal-math"
! CHECK: "-fconvert=little-endian"
! CHECK: "-fpass-plugin=Bye
+! CHECK: "-freal-sum-reassociation"
! CHECK: "-fversion-loops-for-stride"
! CHECK: "-fno-ppc-native-vector-element-order"
! CHECK: "-fppc-native-vector-element-order"
diff --git a/flang/test/Lower/split-sum-expression-tree-lowering.f90 b/flang/test/Lower/split-sum-expression-tree-lowering.f90
index e6287533ed75e..2e50cf72136a3 100644
--- a/flang/test/Lower/split-sum-expression-tree-lowering.f90
+++ b/flang/test/Lower/split-sum-expression-tree-lowering.f90
@@ -1,4 +1,5 @@
-! RUN: %flang_fc1 -emit-hlfir -mllvm -enable-split-sum-expression-tree-lowering -o - %s | FileCheck %s --check-prefixes=SPLIT,NO-REWRITE
+! RUN: %flang_fc1 -emit-hlfir -freal-sum-reassociation -o - %s | FileCheck %s --check-prefixes=SPLIT,NO-REWRITE
+! RUN: %flang_fc1 -emit-hlfir -freal-sum-reassociation -fno-real-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
! Default: (((x + a*b) + c*d) + e*f)
>From 5a749abaf40e1fc827596eb6f981eb1d84ed776f Mon Sep 17 00:00:00 2001
From: Tom Eccles <tom.eccles at arm.com>
Date: Tue, 7 Jul 2026 16:33:41 +0100
Subject: [PATCH 2/2] Make the option visible in --help
---
clang/include/clang/Options/FlangOptions.td | 16 ++++++++++++----
flang/test/Driver/driver-help.f90 | 6 ++++++
2 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/clang/include/clang/Options/FlangOptions.td b/clang/include/clang/Options/FlangOptions.td
index d2b2a03e9eb9b..bafc063663fe2 100644
--- a/clang/include/clang/Options/FlangOptions.td
+++ b/clang/include/clang/Options/FlangOptions.td
@@ -313,11 +313,19 @@ def fno_fast_real_mod : Flag<["-"], "fno-fast-real-mod">, Group<f_Group>,
defm real_sum_reassociation
: BoolOptionWithoutMarshalling<
"f", "real-sum-reassociation",
- PosFlag<SetTrue, [HelpHidden], [],
+ PosFlag<SetTrue, [], [],
"Enable Fortran-standard compliant reassociation within "
- "individual REAL sum expressions">,
- NegFlag<SetFalse, [HelpHidden], [],
- "Disable reassociation within individual REAL sum expressions">>;
+ "individual REAL sum expressions. This may change exact "
+ "floating-point results">,
+ NegFlag<SetFalse, [], [],
+ "Disable reassociation within individual REAL sum "
+ "expressions">>,
+ DocBrief<[{
+ Enable Fortran-standard compliant reassociation within individual
+ ``REAL`` sum expressions. This can improve optimization opportunities
+ and may change exact floating-point results while preserving
+ standard-conforming Fortran semantics.
+ }]>;
defm init_global_zero : BoolOptionWithoutMarshalling<"f", "init-global-zero",
PosFlag<SetTrue, [], [], "Zero initialize globals without default initialization (default)">,
diff --git a/flang/test/Driver/driver-help.f90 b/flang/test/Driver/driver-help.f90
index 4c3609db80b9a..e77fc460850b2 100644
--- a/flang/test/Driver/driver-help.f90
+++ b/flang/test/Driver/driver-help.f90
@@ -7,9 +7,15 @@
! HELP:USAGE: flang
! HELP-EMPTY:
! HELP-NEXT:OPTIONS:
+! HELP: -freal-sum-reassociation
+! HELP: Enable Fortran-standard compliant reassociation within individual REAL sum expressions
+! HELP: may change exact floating-point results
! HELP-FC1:USAGE: flang
! HELP-FC1-EMPTY:
! HELP-FC1-NEXT:OPTIONS:
+! HELP-FC1: -freal-sum-reassociation
+! HELP-FC1: Enable Fortran-standard compliant reassociation within individual REAL sum expressions
+! HELP-FC1: may change exact floating-point results
! ERROR: error: unknown argument '-helps'; did you mean '-help'
More information about the llvm-branch-commits
mailing list