[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