Author: Madhur Amilkanthwar
Date: 2026-08-31T09:56:48+05:30
New Revision: e448a895252d5dd74f85450a2b1438e39096865c

URL: 
https://github.com/llvm/llvm-project/commit/e448a895252d5dd74f85450a2b1438e39096865c
DIFF: 
https://github.com/llvm/llvm-project/commit/e448a895252d5dd74f85450a2b1438e39096865c.diff

LOG: [Clang][Flang] Enable loop interchange by default at >O1 opt levels 
(#216920)

PR #124911 enabled the LoopInterchange pass by default in the LLVM
optimization pipeline (the PipelineTuningOptions default used by opt),
but the clang and flang frontends override that default and keep it off.
As a result, driving the compiler through clang or flang never runs loop
interchange unless -floop-interchange is passed explicitly.

Default -floop-interchange on in both frontends so they match the LLVM
pipeline default. opt enables the pass unconditionally
(PipelineTuningOptions::LoopInterchange defaults to true); the
optimization level gating happens naturally because the pass only lives
in the module optimization pipeline, so it runs at -O1 and above and is
absent at -O0. The decision is made in the frontend (-cc1/-fc1) for both
clang and flang, mirroring -funroll-loops; the flang driver only
forwards an explicit -f[no-]loop-interchange. An explicit
-fno-loop-interchange keeps it off at any level.

Compile-time impact is largely due to enablement of the new pass:
https://llvm-compile-time-tracker.com/?config=Overview&stat=instructions%3Au&remote=madhur13490

Added: 
    

Modified: 
    clang/lib/Driver/ToolChains/CommonArgs.cpp
    clang/lib/Frontend/CompilerInvocation.cpp
    clang/test/Driver/clang_f_opts.c
    flang/lib/Frontend/CompilerInvocation.cpp
    flang/test/Driver/loop-interchange.f90

Removed: 
    


################################################################################
diff  --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp 
b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 0628ab51b39e6..e61a08e86dcff 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -3620,9 +3620,10 @@ void tools::handleVectorizeSLPArgs(const ArgList &Args,
 
 void tools::handleInterchangeLoopsArgs(const ArgList &Args,
                                        ArgStringList &CmdArgs) {
-  if (Args.hasFlag(options::OPT_floop_interchange,
-                   options::OPT_fno_loop_interchange, false))
-    CmdArgs.push_back("-floop-interchange");
+  // Forward the user's explicit choice; the frontend applies the -O3
+  // default when neither flag is present.
+  Args.AddLastArg(CmdArgs, options::OPT_floop_interchange,
+                  options::OPT_fno_loop_interchange);
 }
 
 std::string tools::complexRangeKindToStr(LangOptions::ComplexRangeKind Range) {

diff  --git a/clang/lib/Frontend/CompilerInvocation.cpp 
b/clang/lib/Frontend/CompilerInvocation.cpp
index 2f5e882d59084..ea8368908879a 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1945,8 +1945,10 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions 
&Opts, ArgList &Args,
   Opts.UnrollLoops =
       Args.hasFlag(OPT_funroll_loops, OPT_fno_unroll_loops,
                    (Opts.OptimizationLevel > 1));
+  // Match the LLVM pipeline default (PipelineTuningOptions::LoopInterchange),
+  // which enables the pass whenever the optimization pipeline runs.
   Opts.InterchangeLoops =
-      Args.hasFlag(OPT_floop_interchange, OPT_fno_loop_interchange, false);
+      Args.hasFlag(OPT_floop_interchange, OPT_fno_loop_interchange, true);
   Opts.FuseLoops = Args.hasFlag(OPT_fexperimental_loop_fusion,
                                 OPT_fno_experimental_loop_fusion, false);
   Opts.BinutilsVersion =

diff  --git a/clang/test/Driver/clang_f_opts.c 
b/clang/test/Driver/clang_f_opts.c
index 5871f1580d6b7..0ec2cb5133b21 100644
--- a/clang/test/Driver/clang_f_opts.c
+++ b/clang/test/Driver/clang_f_opts.c
@@ -51,6 +51,16 @@
 // RUN: %clang -### -S -floop-interchange -fno-loop-interchange %s 2>&1 | 
FileCheck -check-prefix=CHECK-NO-INTERCHANGE-LOOPS %s
 // CHECK-INTERCHANGE-LOOPS: "-floop-interchange"
 // CHECK-NO-INTERCHANGE-LOOPS: "-fno-loop-interchange"
+//
+// Loop interchange matches the LLVM pipeline default: on whenever the
+// optimization pipeline runs (-O1 and above), off with an explicit
+// -fno-loop-interchange.
+// RUN: %clang -c -mllvm -print-pipeline-passes -O1 %s -o /dev/null 2>&1 | 
FileCheck --check-prefixes=INTERCHANGE-ON %s
+// RUN: %clang -c -mllvm -print-pipeline-passes -O2 %s -o /dev/null 2>&1 | 
FileCheck --check-prefixes=INTERCHANGE-ON %s
+// RUN: %clang -c -mllvm -print-pipeline-passes -O3 %s -o /dev/null 2>&1 | 
FileCheck --check-prefixes=INTERCHANGE-ON %s
+// RUN: %clang -c -fno-loop-interchange -mllvm -print-pipeline-passes -O3 %s 
-o /dev/null 2>&1 | FileCheck --check-prefixes=INTERCHANGE-OFF %s
+// INTERCHANGE-ON: loop-interchange
+// INTERCHANGE-OFF-NOT: loop-interchange
 
 // RUN: %clang -### -S -fexperimental-loop-fusion %s -o /dev/null 2>&1 | 
FileCheck -check-prefix=CHECK-FUSE-LOOPS %s
 // CHECK-FUSE-LOOPS: "-fexperimental-loop-fusion"

diff  --git a/flang/lib/Frontend/CompilerInvocation.cpp 
b/flang/lib/Frontend/CompilerInvocation.cpp
index 988f8cb65d176..43986666cc734 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -321,8 +321,11 @@ static void 
parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
                    clang::options::OPT_fno_fp_sum_reassociation, false))
     opts.SplitSumExpressionTree = 1;
 
-  if (args.getLastArg(clang::options::OPT_floop_interchange))
-    opts.InterchangeLoops = 1;
+  // Match the LLVM pipeline default (PipelineTuningOptions::LoopInterchange),
+  // which enables the pass whenever the optimization pipeline runs.
+  opts.InterchangeLoops =
+      args.hasFlag(clang::options::OPT_floop_interchange,
+                   clang::options::OPT_fno_loop_interchange, true);
 
   if (args.getLastArg(clang::options::OPT_fexperimental_loop_fusion))
     opts.FuseLoops = 1;

diff  --git a/flang/test/Driver/loop-interchange.f90 
b/flang/test/Driver/loop-interchange.f90
index 1e5a11902709c..0370f7c54866d 100644
--- a/flang/test/Driver/loop-interchange.f90
+++ b/flang/test/Driver/loop-interchange.f90
@@ -1,15 +1,18 @@
+! The driver only forwards an explicit -f[no-]loop-interchange; the -O3
+! default is applied in the frontend, so it is not visible in -###.
 ! 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-NO-LOOP-INTERCHANGE %s
 ! RUN: %flang -### -S -O3 %s 2>&1 | FileCheck 
-check-prefix=CHECK-NO-LOOP-INTERCHANGE %s
-! RUN: %flang -### -S -Os %s 2>&1 | FileCheck 
-check-prefix=CHECK-NO-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-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
+!
+! Loop interchange matches the LLVM pipeline default: on whenever the
+! optimization pipeline runs (-O1 and above), off with an explicit
+! -fno-loop-interchange.
+! RUN: %flang_fc1 -emit-llvm -O1 -mllvm -print-pipeline-passes -o /dev/null %s 
2>&1 | FileCheck -check-prefix=CHECK-LOOP-INTERCHANGE-PASS %s
+! RUN: %flang_fc1 -emit-llvm -O2 -mllvm -print-pipeline-passes -o /dev/null %s 
2>&1 | FileCheck -check-prefix=CHECK-LOOP-INTERCHANGE-PASS %s
+! RUN: %flang_fc1 -emit-llvm -O3 -mllvm -print-pipeline-passes -o /dev/null %s 
2>&1 | FileCheck -check-prefix=CHECK-LOOP-INTERCHANGE-PASS %s
+! RUN: %flang_fc1 -emit-llvm -O3 -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
 


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to