[clang] [flang] [flang] add -floop-interchange and enable it with opt levels (PR #140182)
Sebastian Pop via cfe-commits
cfe-commits at lists.llvm.org
Tue May 20 13:02:15 PDT 2025
https://github.com/sebpop updated https://github.com/llvm/llvm-project/pull/140182
>From 46efee7d48a11794fc103cf67b21796d8e5f3408 Mon Sep 17 00:00:00 2001
From: Sebastian Pop <spop at nvidia.com>
Date: Mon, 12 May 2025 21:56:03 +0000
Subject: [PATCH 1/3] [flang] add -floop-interchange to flang driver
This patch allows flang to recognize the flags -floop-interchange and
-fno-loop-interchange. -floop-interchange adds the loop interchange pass to the
pass pipeline.
---
clang/include/clang/Driver/Options.td | 4 ++--
clang/lib/Driver/ToolChains/Flang.cpp | 3 +++
flang/docs/ReleaseNotes.md | 2 ++
flang/include/flang/Frontend/CodeGenOptions.def | 1 +
flang/lib/Frontend/CompilerInvocation.cpp | 3 +++
flang/lib/Frontend/FrontendActions.cpp | 1 +
flang/test/Driver/loop-interchange.f90 | 7 +++++++
7 files changed, 19 insertions(+), 2 deletions(-)
create mode 100644 flang/test/Driver/loop-interchange.f90
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index bd8df8f6a749a..c8c675bc17e7d 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4186,9 +4186,9 @@ def ftrap_function_EQ : Joined<["-"], "ftrap-function=">, Group<f_Group>,
HelpText<"Issue call to specified function rather than a trap instruction">,
MarshallingInfoString<CodeGenOpts<"TrapFuncName">>;
def floop_interchange : Flag<["-"], "floop-interchange">, Group<f_Group>,
- HelpText<"Enable the loop interchange pass">, Visibility<[ClangOption, CC1Option]>;
+ HelpText<"Enable the loop interchange pass">, Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>;
def fno_loop_interchange: Flag<["-"], "fno-loop-interchange">, Group<f_Group>,
- HelpText<"Disable the loop interchange pass">, Visibility<[ClangOption, CC1Option]>;
+ HelpText<"Disable the loop interchange pass">, Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>;
def funroll_loops : Flag<["-"], "funroll-loops">, Group<f_Group>,
HelpText<"Turn on loop unroller">, Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>;
def fno_unroll_loops : Flag<["-"], "fno-unroll-loops">, Group<f_Group>,
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index b1ca747e68b89..c6c7a0b75a987 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -152,6 +152,9 @@ void Flang::addCodegenOptions(const ArgList &Args,
!stackArrays->getOption().matches(options::OPT_fno_stack_arrays))
CmdArgs.push_back("-fstack-arrays");
+ Args.AddLastArg(CmdArgs, options::OPT_floop_interchange,
+ options::OPT_fno_loop_interchange);
+
handleVectorizeLoopsArgs(Args, CmdArgs);
handleVectorizeSLPArgs(Args, CmdArgs);
diff --git a/flang/docs/ReleaseNotes.md b/flang/docs/ReleaseNotes.md
index b356f64553d7e..c76635d121d58 100644
--- a/flang/docs/ReleaseNotes.md
+++ b/flang/docs/ReleaseNotes.md
@@ -32,6 +32,8 @@ page](https://llvm.org/releases/).
## New Compiler Flags
+* -floop-interchange is now recognized by flang.
+
## Windows Support
## Fortran Language Changes in Flang
diff --git a/flang/include/flang/Frontend/CodeGenOptions.def b/flang/include/flang/Frontend/CodeGenOptions.def
index d9dbd274e83e5..7ced60f512219 100644
--- a/flang/include/flang/Frontend/CodeGenOptions.def
+++ b/flang/include/flang/Frontend/CodeGenOptions.def
@@ -35,6 +35,7 @@ CODEGENOPT(PrepareForThinLTO , 1, 0) ///< Set when -flto=thin is enabled on the
CODEGENOPT(StackArrays, 1, 0) ///< -fstack-arrays (enable the stack-arrays pass)
CODEGENOPT(VectorizeLoop, 1, 0) ///< Enable loop vectorization.
CODEGENOPT(VectorizeSLP, 1, 0) ///< Enable SLP vectorization.
+CODEGENOPT(InterchangeLoops, 1, 0) ///< Enable loop interchange.
CODEGENOPT(LoopVersioning, 1, 0) ///< Enable loop versioning.
CODEGENOPT(UnrollLoops, 1, 0) ///< Enable loop unrolling
CODEGENOPT(AliasAnalysis, 1, 0) ///< Enable alias analysis pass
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 238079a09ef3a..67fb0924def71 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -269,6 +269,9 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
clang::driver::options::OPT_fno_stack_arrays, false))
opts.StackArrays = 1;
+ if (args.getLastArg(clang::driver::options::OPT_floop_interchange))
+ opts.InterchangeLoops = 1;
+
if (args.getLastArg(clang::driver::options::OPT_vectorize_loops))
opts.VectorizeLoop = 1;
diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index e5a15c555fa5e..38dfaadf1dff9 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -922,6 +922,7 @@ void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) {
if (ci.isTimingEnabled())
si.getTimePasses().setOutStream(ci.getTimingStreamLLVM());
pto.LoopUnrolling = opts.UnrollLoops;
+ pto.LoopInterchange = opts.InterchangeLoops;
pto.LoopInterleaving = opts.UnrollLoops;
pto.LoopVectorization = opts.VectorizeLoop;
pto.SLPVectorization = opts.VectorizeSLP;
diff --git a/flang/test/Driver/loop-interchange.f90 b/flang/test/Driver/loop-interchange.f90
new file mode 100644
index 0000000000000..30ce2734d0466
--- /dev/null
+++ b/flang/test/Driver/loop-interchange.f90
@@ -0,0 +1,7 @@
+! RUN: %flang -### -S -floop-interchange %s 2>&1 | FileCheck -check-prefix=CHECK-LOOP-INTERCHANGE %s
+! RUN: %flang -### -S -fno-loop-interchange %s 2>&1 | FileCheck -check-prefix=CHECK-NO-LOOP-INTERCHANGE %s
+! CHECK-LOOP-INTERCHANGE: "-floop-interchange"
+! CHECK-NO-LOOP-INTERCHANGE: "-fno-loop-interchange"
+
+program test
+end program
>From 9dc3774db84e908516a184fa7b7fd242b68a22d1 Mon Sep 17 00:00:00 2001
From: Sebastian Pop <spop at nvidia.com>
Date: Fri, 16 May 2025 03:02:54 +0000
Subject: [PATCH 2/3] [flang] enable loop-interchange at O3, O2, and Os
---
clang/lib/Driver/ToolChains/CommonArgs.cpp | 13 +++++++++++++
clang/lib/Driver/ToolChains/CommonArgs.h | 4 ++++
clang/lib/Driver/ToolChains/Flang.cpp | 4 +---
flang/docs/ReleaseNotes.md | 1 +
flang/test/Driver/loop-interchange.f90 | 8 +++++++-
5 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 632027c4a944c..83be3a8e27302 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -3149,3 +3149,16 @@ void tools::handleVectorizeSLPArgs(const ArgList &Args,
options::OPT_fno_slp_vectorize, EnableSLPVec))
CmdArgs.push_back("-vectorize-slp");
}
+
+void tools::handleInterchangeLoopsArgs(const ArgList &Args,
+ ArgStringList &CmdArgs) {
+ // FIXME: instead of relying on shouldEnableVectorizerAtOLevel, we may want to
+ // implement a separate function to infer loop interchange from opt level.
+ // For now, enable loop-interchange at the same opt levels as loop-vectorize.
+ bool EnableInterchange = shouldEnableVectorizerAtOLevel(Args, false);
+ OptSpecifier InterchangeAliasOption =
+ EnableInterchange ? options::OPT_O_Group : options::OPT_floop_interchange;
+ if (Args.hasFlag(options::OPT_floop_interchange, InterchangeAliasOption,
+ options::OPT_fno_loop_interchange, EnableInterchange))
+ CmdArgs.push_back("-floop-interchange");
+}
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h
index 96bc0619dcbc0..6d36a0e8bf493 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.h
+++ b/clang/lib/Driver/ToolChains/CommonArgs.h
@@ -259,6 +259,10 @@ void renderCommonIntegerOverflowOptions(const llvm::opt::ArgList &Args,
bool shouldEnableVectorizerAtOLevel(const llvm::opt::ArgList &Args,
bool isSlpVec);
+/// Enable -floop-interchange based on the optimization level selected.
+void handleInterchangeLoopsArgs(const llvm::opt::ArgList &Args,
+ llvm::opt::ArgStringList &CmdArgs);
+
/// Enable -fvectorize based on the optimization level selected.
void handleVectorizeLoopsArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs);
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index c6c7a0b75a987..54176381b6e5b 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -152,9 +152,7 @@ void Flang::addCodegenOptions(const ArgList &Args,
!stackArrays->getOption().matches(options::OPT_fno_stack_arrays))
CmdArgs.push_back("-fstack-arrays");
- Args.AddLastArg(CmdArgs, options::OPT_floop_interchange,
- options::OPT_fno_loop_interchange);
-
+ handleInterchangeLoopsArgs(Args, CmdArgs);
handleVectorizeLoopsArgs(Args, CmdArgs);
handleVectorizeSLPArgs(Args, CmdArgs);
diff --git a/flang/docs/ReleaseNotes.md b/flang/docs/ReleaseNotes.md
index c76635d121d58..36be369595ffd 100644
--- a/flang/docs/ReleaseNotes.md
+++ b/flang/docs/ReleaseNotes.md
@@ -33,6 +33,7 @@ page](https://llvm.org/releases/).
## New Compiler Flags
* -floop-interchange is now recognized by flang.
+* -floop-interchange is enabled by default at -O2 and above.
## Windows Support
diff --git a/flang/test/Driver/loop-interchange.f90 b/flang/test/Driver/loop-interchange.f90
index 30ce2734d0466..d5d62e9a777d2 100644
--- a/flang/test/Driver/loop-interchange.f90
+++ b/flang/test/Driver/loop-interchange.f90
@@ -1,7 +1,13 @@
! RUN: %flang -### -S -floop-interchange %s 2>&1 | FileCheck -check-prefix=CHECK-LOOP-INTERCHANGE %s
! RUN: %flang -### -S -fno-loop-interchange %s 2>&1 | FileCheck -check-prefix=CHECK-NO-LOOP-INTERCHANGE %s
+! RUN: %flang -### -S -O0 %s 2>&1 | FileCheck -check-prefix=CHECK-NO-LOOP-INTERCHANGE %s
+! RUN: %flang -### -S -O1 %s 2>&1 | FileCheck -check-prefix=CHECK-NO-LOOP-INTERCHANGE %s
+! RUN: %flang -### -S -O2 %s 2>&1 | FileCheck -check-prefix=CHECK-LOOP-INTERCHANGE %s
+! RUN: %flang -### -S -O3 %s 2>&1 | FileCheck -check-prefix=CHECK-LOOP-INTERCHANGE %s
+! RUN: %flang -### -S -Os %s 2>&1 | FileCheck -check-prefix=CHECK-LOOP-INTERCHANGE %s
+! RUN: %flang -### -S -Oz %s 2>&1 | FileCheck -check-prefix=CHECK-NO-LOOP-INTERCHANGE %s
! CHECK-LOOP-INTERCHANGE: "-floop-interchange"
-! CHECK-NO-LOOP-INTERCHANGE: "-fno-loop-interchange"
+! CHECK-NO-LOOP-INTERCHANGE-NOT: "-floop-interchange"
program test
end program
>From 0b81d78ae5bcd78e1e5bfb7609f38c1ad16c079c Mon Sep 17 00:00:00 2001
From: Sebastian Pop <spop at nvidia.com>
Date: Fri, 16 May 2025 21:46:04 +0000
Subject: [PATCH 3/3] test loop-interchange in pass pipeline
---
flang/test/Driver/loop-interchange.f90 | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/flang/test/Driver/loop-interchange.f90 b/flang/test/Driver/loop-interchange.f90
index d5d62e9a777d2..5d3ec71c59874 100644
--- a/flang/test/Driver/loop-interchange.f90
+++ b/flang/test/Driver/loop-interchange.f90
@@ -8,6 +8,10 @@
! RUN: %flang -### -S -Oz %s 2>&1 | FileCheck -check-prefix=CHECK-NO-LOOP-INTERCHANGE %s
! CHECK-LOOP-INTERCHANGE: "-floop-interchange"
! CHECK-NO-LOOP-INTERCHANGE-NOT: "-floop-interchange"
+! RUN: %flang_fc1 -emit-llvm -O2 -floop-interchange -mllvm -print-pipeline-passes -o /dev/null %s 2>&1 | FileCheck -check-prefix=CHECK-LOOP-INTERCHANGE-PASS %s
+! RUN: %flang_fc1 -emit-llvm -O2 -fno-loop-interchange -mllvm -print-pipeline-passes -o /dev/null %s 2>&1 | FileCheck -check-prefix=CHECK-NO-LOOP-INTERCHANGE-PASS %s
+! CHECK-LOOP-INTERCHANGE-PASS: loop-interchange
+! CHECK-NO-LOOP-INTERCHANGE-PASS-NOT: loop-interchange
program test
end program
More information about the cfe-commits
mailing list