[flang-commits] [flang] [flang] Enable FIR loop invariant code motion by default (PR #218703)
via flang-commits
flang-commits at lists.llvm.org
Tue Aug 25 08:47:42 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
Author: Caroline Newcombe (cenewcombe)
<details>
<summary>Changes</summary>
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.
Tests updated:
- `basic-program.fir`, `bbc-mlir-pass-pipeline.f90`, `mlir-pass-pipeline.f90` — pass added to the expected pipeline, since they run with `-O2`.
- `tco-test-gen.fir` — moved a check line which now lands in the preheader.
---
Full diff: https://github.com/llvm/llvm-project/pull/218703.diff
8 Files Affected:
- (modified) flang/docs/ReleaseNotes.md (+5)
- (modified) flang/include/flang/Optimizer/Passes/CommandLineOpts.h (+1-1)
- (modified) flang/lib/Optimizer/Passes/CommandLineOpts.cpp (+1-1)
- (modified) flang/lib/Optimizer/Passes/Pipelines.cpp (+1-1)
- (modified) flang/test/Driver/bbc-mlir-pass-pipeline.f90 (+3)
- (modified) flang/test/Driver/mlir-pass-pipeline.f90 (+3)
- (modified) flang/test/Driver/tco-test-gen.fir (+1-2)
- (modified) flang/test/Fir/basic-program.fir (+3)
``````````diff
diff --git a/flang/docs/ReleaseNotes.md b/flang/docs/ReleaseNotes.md
index bbc7084c4a757..bb08bb10f3878 100644
--- a/flang/docs/ReleaseNotes.md
+++ b/flang/docs/ReleaseNotes.md
@@ -47,6 +47,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 232b27a148ab2..a0892dea2158d 100644
--- a/flang/lib/Optimizer/Passes/Pipelines.cpp
+++ b/flang/lib/Optimizer/Passes/Pipelines.cpp
@@ -224,7 +224,7 @@ void createDefaultFIROptimizerPassPipeline(mlir::PassManager &pm,
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 438804ce42b76..337273e81454b 100644
--- a/flang/test/Driver/tco-test-gen.fir
+++ b/flang/test/Driver/tco-test-gen.fir
@@ -68,6 +68,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
@@ -90,8 +91,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
``````````
</details>
https://github.com/llvm/llvm-project/pull/218703
More information about the flang-commits
mailing list