[flang-commits] [flang] edbf358 - [flang] Enable FIR loop invariant code motion by default (#218703)
via flang-commits
flang-commits at lists.llvm.org
Mon Aug 31 08:20:08 PDT 2026
Author: Caroline Newcombe
Date: 2026-08-31T11:20:03-04:00
New Revision: edbf358d014942a17953c3ccfcf9f206201179ba
URL: https://github.com/llvm/llvm-project/commit/edbf358d014942a17953c3ccfcf9f206201179ba
DIFF: https://github.com/llvm/llvm-project/commit/edbf358d014942a17953c3ccfcf9f206201179ba.diff
LOG: [flang] Enable FIR loop invariant code motion by default (#218703)
The FIR loop invariant code motion pass was added in #173438, where it
was disabled by default. This enables it for optimization levels above
`-O0`. The option `-disable-fir-licm` has been added in place of
`-enable-fir-licm`. The pass itself is unchanged.
Relates to #208086 and fixes #110613. Tests updated.
Assisted-by: Copilot
Added:
Modified:
flang/docs/ReleaseNotes.md
flang/include/flang/Optimizer/Passes/CommandLineOpts.h
flang/lib/Optimizer/Passes/CommandLineOpts.cpp
flang/lib/Optimizer/Passes/Pipelines.cpp
flang/test/Driver/bbc-mlir-pass-pipeline.f90
flang/test/Driver/mlir-pass-pipeline.f90
flang/test/Driver/tco-test-gen.fir
flang/test/Fir/basic-program.fir
Removed:
################################################################################
diff --git a/flang/docs/ReleaseNotes.md b/flang/docs/ReleaseNotes.md
index 079a8e5ba0e94..0815355a86844 100644
--- a/flang/docs/ReleaseNotes.md
+++ b/flang/docs/ReleaseNotes.md
@@ -52,6 +52,11 @@ page](https://llvm.org/releases/).
compressing DWARF debug info in ELF object files using zlib or zstd,
reducing debug information size in compiled binaries.
+- The FIR loop invariant code motion pass (`flang-licm`) is now enabled by
+ default at optimization levels above `-O0`. It can be turned off with
+ `-mmlir -disable-fir-licm`. The `-mmlir -enable-fir-licm` option that
+ previously opted into the pass has been removed.
+
## New Compiler Flags
- Added the gfortran-compatible `-ffpe-trap=` flag, which sets the initial
floating-point exception halting mode of the main program. It takes a
diff --git a/flang/include/flang/Optimizer/Passes/CommandLineOpts.h b/flang/include/flang/Optimizer/Passes/CommandLineOpts.h
index d42ce8b762e63..b2ce29a2fefe0 100644
--- a/flang/include/flang/Optimizer/Passes/CommandLineOpts.h
+++ b/flang/include/flang/Optimizer/Passes/CommandLineOpts.h
@@ -53,8 +53,8 @@ extern llvm::codegenoptions::DebugInfoKind noDebugInfo;
/// Optimizer Passes
extern llvm::cl::opt<bool> disableCfgConversion;
extern llvm::cl::opt<bool> disableFirAliasTags;
+extern llvm::cl::opt<bool> disableFirLICM;
extern llvm::cl::opt<bool> disableFirMao;
-extern llvm::cl::opt<bool> enableFirLICM;
extern llvm::cl::opt<bool> useOldAliasTags;
/// Experimental option to replace the stack-arrays and memory-allocation-opt
diff --git a/flang/lib/Optimizer/Passes/CommandLineOpts.cpp b/flang/lib/Optimizer/Passes/CommandLineOpts.cpp
index d2af7dd5ecd64..151b01d29774a 100644
--- a/flang/lib/Optimizer/Passes/CommandLineOpts.cpp
+++ b/flang/lib/Optimizer/Passes/CommandLineOpts.cpp
@@ -60,7 +60,7 @@ cl::opt<bool> useOldAliasTags(
cl::desc("Use a single TBAA tree for all functions and do not use "
"the FIR alias tags pass"),
cl::init(false), cl::Hidden);
-EnableOption(FirLICM, "fir-licm", "FIR loop invariant code motion");
+DisableOption(FirLICM, "fir-licm", "FIR loop invariant code motion");
EnableOption(AllocationPlacement, "allocation-placement",
"unified array allocation placement (experimental; replaces "
"stack-arrays and memory-allocation-opt)");
diff --git a/flang/lib/Optimizer/Passes/Pipelines.cpp b/flang/lib/Optimizer/Passes/Pipelines.cpp
index ad59f824611d2..1f99a48505368 100644
--- a/flang/lib/Optimizer/Passes/Pipelines.cpp
+++ b/flang/lib/Optimizer/Passes/Pipelines.cpp
@@ -218,7 +218,7 @@ void createDefaultFIRPreCFGOptimizerPassPipeline(
pm.addPass(mlir::createCSEPass());
// Run LICM after CSE, which may reduce the number of operations to hoist.
- if (enableFirLICM && pc.OptLevel != llvm::OptimizationLevel::O0)
+ if (!disableFirLICM && pc.OptLevel != llvm::OptimizationLevel::O0)
pm.addPass(fir::createLoopInvariantCodeMotion());
// Polymorphic types
diff --git a/flang/test/Driver/bbc-mlir-pass-pipeline.f90 b/flang/test/Driver/bbc-mlir-pass-pipeline.f90
index 80328c84794cb..23884dc53bd34 100644
--- a/flang/test/Driver/bbc-mlir-pass-pipeline.f90
+++ b/flang/test/Driver/bbc-mlir-pass-pipeline.f90
@@ -47,6 +47,9 @@
! CHECK-NEXT: (S) 0 num-cse'd - Number of operations CSE'd
! CHECK-NEXT: (S) 0 num-dce'd - Number of operations DCE'd
+! CHECK-NEXT: 'func.func' Pipeline
+! CHECK-NEXT: LoopInvariantCodeMotion
+
! CHECK-NEXT: PolymorphicOpConversion
! CHECK-NEXT: 'func.func' Pipeline
! CHECK-NEXT: SelectOpsConversion
diff --git a/flang/test/Driver/mlir-pass-pipeline.f90 b/flang/test/Driver/mlir-pass-pipeline.f90
index 13910af836186..0c13f14f35974 100644
--- a/flang/test/Driver/mlir-pass-pipeline.f90
+++ b/flang/test/Driver/mlir-pass-pipeline.f90
@@ -136,6 +136,9 @@
! ALL-NEXT: (S) 0 num-cse'd - Number of operations CSE'd
! ALL-NEXT: (S) 0 num-dce'd - Number of operations DCE'd
+! O2-NEXT: 'func.func' Pipeline
+! O2-NEXT: LoopInvariantCodeMotion
+
! ALL-NEXT: PolymorphicOpConversion
! ALL-NEXT: 'func.func' Pipeline
! ALL-NEXT: SelectOpsConversion
diff --git a/flang/test/Driver/tco-test-gen.fir b/flang/test/Driver/tco-test-gen.fir
index 4c9f9c1ed79d3..6bcb37fc7bb0e 100644
--- a/flang/test/Driver/tco-test-gen.fir
+++ b/flang/test/Driver/tco-test-gen.fir
@@ -66,6 +66,7 @@ func.func @_QPtest(%arg0: !fir.ref<i32> {fir.bindc_name = "num"}, %arg1: !fir.re
// CHECK: %[[VAL_10:.*]] = llvm.sext %[[VAL_9]] : i32 to i64
// CHECK: %[[VAL_11:.*]] = llvm.trunc %[[VAL_6]] : i64 to i32
+// CHECK: %[[VAL_21:.*]] = llvm.trunc %[[VAL_10]] : i64 to i32
// CHECK: %[[VAL_12:.*]] = llvm.sub %[[VAL_8]], %[[VAL_6]] : i64
// CHECK: %[[VAL_13:.*]] = llvm.add %[[VAL_12]], %[[VAL_10]] : i64
// CHECK: %[[VAL_14:.*]] = llvm.sdiv %[[VAL_13]], %[[VAL_10]] : i64
@@ -88,8 +89,6 @@ func.func @_QPtest(%arg0: !fir.ref<i32> {fir.bindc_name = "num"}, %arg1: !fir.re
// AA: llvm.store %[[VAL_20]], %[[ARG0]] {tbaa = [#llvm.tbaa_tag<base_type = <id = "dummy arg data/_QFtestEnum", members = {<#llvm.tbaa_type_desc<id = "dummy arg data", members = {<#llvm.tbaa_type_desc<id = "any data access", members = {<#llvm.tbaa_type_desc<id = "any access", members = {<#llvm.tbaa_root<id = "Flang function root _QPtest">, 0>}>, 0>}>, 0>}>, 0>}>, access_type = <id = "dummy arg data/_QFtestEnum", members = {<#llvm.tbaa_type_desc<id = "dummy arg data", members = {<#llvm.tbaa_type_desc<id = "any data access", members = {<#llvm.tbaa_type_desc<id = "any access", members = {<#llvm.tbaa_root<id = "Flang function root _QPtest">, 0>}>, 0>}>, 0>}>, 0>}>, offset = 0>]} : i32, !llvm.ptr
// NOAA: llvm.store %[[VAL_20]], %[[ARG0]] : i32, !llvm.ptr
-// CHECK: %[[VAL_21:.*]] = llvm.trunc %[[VAL_10]] : i64 to i32
-
// AA: %[[VAL_22:.*]] = llvm.load %[[VAL_1]] {tbaa = [#llvm.tbaa_tag<base_type = <id = "allocated data/_QFtestEi", members = {<#llvm.tbaa_type_desc<id = "allocated data", members = {<#llvm.tbaa_type_desc<id = "any data access", members = {<#llvm.tbaa_type_desc<id = "any access", members = {<#llvm.tbaa_root<id = "Flang function root _QPtest">, 0>}>, 0>}>, 0>}>, 0>}>, access_type = <id = "allocated data/_QFtestEi", members = {<#llvm.tbaa_type_desc<id = "allocated data", members = {<#llvm.tbaa_type_desc<id = "any data access", members = {<#llvm.tbaa_type_desc<id = "any access", members = {<#llvm.tbaa_root<id = "Flang function root _QPtest">, 0>}>, 0>}>, 0>}>, 0>}>, offset = 0>]} : !llvm.ptr -> i32
// NOAA: %[[VAL_22:.*]] = llvm.load %{{.*}} : !llvm.ptr -> i32
diff --git a/flang/test/Fir/basic-program.fir b/flang/test/Fir/basic-program.fir
index fa8f666b7b891..51f4699bde7bf 100644
--- a/flang/test/Fir/basic-program.fir
+++ b/flang/test/Fir/basic-program.fir
@@ -119,6 +119,9 @@ func.func @_QQmain() {
// PASSES-NEXT: (S) 0 num-cse'd - Number of operations CSE'd
// PASSES-NEXT: (S) 0 num-dce'd - Number of operations DCE'd
+// PASSES-NEXT: 'func.func' Pipeline
+// PASSES-NEXT: LoopInvariantCodeMotion
+
// PASSES-NEXT: PolymorphicOpConversion
// PASSES-NEXT: 'func.func' Pipeline
// PASSES-NEXT: SelectOpsConversion
More information about the flang-commits
mailing list