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
