[Mlir-commits] [mlir] [mlir][scf] Declare ControlFlow as a dependent dialect (PR #216852)

Alessandro Potenza llvmlistbot at llvm.org
Mon Aug 17 15:47:05 PDT 2026


https://github.com/alepot55 updated https://github.com/llvm/llvm-project/pull/216852

>From 97cf699537d869feca9c54991606173776724486 Mon Sep 17 00:00:00 2001
From: Alessandro Potenza <ap.alessandro.potenza at gmail.com>
Date: Mon, 17 Aug 2026 23:00:38 +0200
Subject: [PATCH 1/2] [mlir][scf] Declare ControlFlow as a dependent dialect

The canonicalization of a multi-block `scf.execute_region` inlines the
region into its parent and materializes `cf.br` operations for the region
entry edge and for every `scf.yield`. The SCF dialect never declared a
dependency on the ControlFlow dialect, so those `cf.br` ops are built even
when `cf` was never loaded into the MLIRContext.

The failure is masked in almost every test because something else in the
input happens to load `cf` first: any `cf` operation in the file loads it
at parse time, and loading the Func dialect loads it too, since the Func
inliner extension calls `getOrLoadDialect<cf::ControlFlowDialect>()`.
Outside of `func.func`, and with no `cf` op anywhere else in the file,
`mlir-opt --canonicalize` fails on valid input.

Add `cf::ControlFlowDialect` to the dialect's `dependentDialects` and add
a regression test that keeps the repro free of both `func.func` and `cf`.

`MLIRControlFlowDialect` is already a public link dependency of
`MLIRSCFDialect`, and `SCF.cpp` already includes `ControlFlowOps.h` before
the generated dialect definition, so no build changes are needed.
---
 mlir/include/mlir/Dialect/SCF/IR/SCFOps.td    |  4 ++-
 .../SCF/canonicalize-dependent-dialects.mlir  | 25 +++++++++++++++++++
 2 files changed, 28 insertions(+), 1 deletion(-)
 create mode 100644 mlir/test/Dialect/SCF/canonicalize-dependent-dialects.mlir

diff --git a/mlir/include/mlir/Dialect/SCF/IR/SCFOps.td b/mlir/include/mlir/Dialect/SCF/IR/SCFOps.td
index 1e7bba2cdad35..a0af0c59a37b5 100644
--- a/mlir/include/mlir/Dialect/SCF/IR/SCFOps.td
+++ b/mlir/include/mlir/Dialect/SCF/IR/SCFOps.td
@@ -42,7 +42,9 @@ def SCF_Dialect : Dialect {
     and then lowered to some final target like LLVM or SPIR-V.
   }];
 
-  let dependentDialects = ["arith::ArithDialect"];
+  // The canonicalization of a multi-block `scf.execute_region` materializes
+  // `cf.br` operations, so the ControlFlow dialect must always be loaded.
+  let dependentDialects = ["arith::ArithDialect", "cf::ControlFlowDialect"];
 }
 
 // Base class for SCF dialect ops.
diff --git a/mlir/test/Dialect/SCF/canonicalize-dependent-dialects.mlir b/mlir/test/Dialect/SCF/canonicalize-dependent-dialects.mlir
new file mode 100644
index 0000000000000..d5eb932eb59d9
--- /dev/null
+++ b/mlir/test/Dialect/SCF/canonicalize-dependent-dialects.mlir
@@ -0,0 +1,25 @@
+// RUN: mlir-opt %s --canonicalize | FileCheck %s
+
+// Canonicalizing a multi-block `scf.execute_region` materializes `cf.br` ops,
+// so the SCF dialect has to declare a dependency on the ControlFlow dialect.
+// This test deliberately contains no `cf` operation and does not use
+// `func.func`: parsing a `cf` operation, or loading the Func dialect (whose
+// inliner extension loads ControlFlow), would load the dialect for unrelated
+// reasons and mask the missing dependency.
+
+// CHECK-LABEL: llvm.func @multi_block_execute_region
+//   CHECK-NOT:   scf.execute_region
+//       CHECK:   llvm.cond_br
+//       CHECK:   llvm.store
+//       CHECK:   llvm.return
+llvm.func @multi_block_execute_region(%c: i1, %p: !llvm.ptr, %x: i64) {
+  scf.execute_region {
+    llvm.cond_br %c, ^bb1, ^bb2
+  ^bb1:
+    llvm.store %x, %p : i64, !llvm.ptr
+    scf.yield
+  ^bb2:
+    scf.yield
+  }
+  llvm.return
+}

>From 4f4b21e432266d2ab1f0f5961404163b00fe34a5 Mon Sep 17 00:00:00 2001
From: Alessandro Potenza <ap.alessandro.potenza at gmail.com>
Date: Tue, 18 Aug 2026 00:46:53 +0200
Subject: [PATCH 2/2] Check for the materialized cf.br ops in the test

---
 mlir/test/Dialect/SCF/canonicalize-dependent-dialects.mlir | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/mlir/test/Dialect/SCF/canonicalize-dependent-dialects.mlir b/mlir/test/Dialect/SCF/canonicalize-dependent-dialects.mlir
index d5eb932eb59d9..c8579167bc071 100644
--- a/mlir/test/Dialect/SCF/canonicalize-dependent-dialects.mlir
+++ b/mlir/test/Dialect/SCF/canonicalize-dependent-dialects.mlir
@@ -11,6 +11,8 @@
 //   CHECK-NOT:   scf.execute_region
 //       CHECK:   llvm.cond_br
 //       CHECK:   llvm.store
+//       CHECK:   cf.br
+//       CHECK:   cf.br
 //       CHECK:   llvm.return
 llvm.func @multi_block_execute_region(%c: i1, %p: !llvm.ptr, %x: i64) {
   scf.execute_region {



More information about the Mlir-commits mailing list