[Mlir-commits] [mlir] 48a6157 - [mlir][Interfaces][NFC] Document that `RegionBranchTerminatorOpInterface` is mandatory (#174978)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Sun Jan 11 02:20:50 PST 2026


Author: Matthias Springer
Date: 2026-01-11T11:20:46+01:00
New Revision: 48a6157eb05186dabad7f3785dfae719a5e8d984

URL: https://github.com/llvm/llvm-project/commit/48a6157eb05186dabad7f3785dfae719a5e8d984
DIFF: https://github.com/llvm/llvm-project/commit/48a6157eb05186dabad7f3785dfae719a5e8d984.diff

LOG: [mlir][Interfaces][NFC] Document that `RegionBranchTerminatorOpInterface` is mandatory (#174978)

Document that implementing the `RegionBranchTerminatorOpInterface` is
mandatory. Omitting this interface on a block terminator that models
region branching may lead to invalid/incomplete analyses and
transformations.

This commit does not change the op/interface semantics. It just puts in
writing an assumption that is made throughout the code base. For
example:

- It is baked into the API design of the `RegionBranchOpInterface`. You
cannot query the region successors of block terminators that do not
implement the `RegionBranchTerminatorOpInterface`:
`RegionBranchOpInterface::getSuccessors()` takes a `RegionBranchPoint`
parameter, and such region branch points can be constructed only from
`RegionBranchTerminatorOpInterface` and not arbitrary `Operation *`.
- Helper functions + default interface method implementations enumerate
region branch points by looking for `RegionBranchTerminatorOpInterface`
and ignoring other operations. E.g.,
`RegionBranchOpInterface::getAllRegionBranchPoints`, default
implementation of `RegionBranchOpInterface::getSuccessorRegions(Region
&)`, default implementation of
`RegionBranchOpInterface::getPredecessorValues`.
- Core analyses such as `DeadCodeAnalysis` look for
`RegionBranchTerminatorOpInterface` and misbehave when the interface is
not implemented. The analysis does not (and cannot) query region
successors of a region branching terminator that does not implement the
`RegionBranchTerminatorOpInterface`. In practice, this means that
forgetting to implement the `RegionBranchTerminatorOpInterface` may
incorrectly classify regions as dead.
- Other analyses / transformations that look for and depend on the
implementation of `RegionBranchTerminatorOpInterface`:
`mlir::getControlFlowPredecessors`,
`AbstractDenseBackwardDataFlowAnalysis`, ownership-based buffer
deallocation pass.

Added: 
    

Modified: 
    mlir/include/mlir/Interfaces/ControlFlowInterfaces.td

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Interfaces/ControlFlowInterfaces.td b/mlir/include/mlir/Interfaces/ControlFlowInterfaces.td
index ecad424e30c75..6c342c97a0fe8 100644
--- a/mlir/include/mlir/Interfaces/ControlFlowInterfaces.td
+++ b/mlir/include/mlir/Interfaces/ControlFlowInterfaces.td
@@ -126,9 +126,10 @@ def RegionBranchOpInterface : OpInterface<"RegionBranchOpInterface"> {
     be side-effect free.
 
     A "region branch point" indicates a point from which a branch originates. It
-    can indicate either a terminator in any of the immediately nested region of
-    this op or `RegionBranchPoint::parent()`. In the latter case, the branch
-    originates from outside of the op, i.e., when first executing this op.
+    can indicate either a `RegionBranchTerminatorOpInterface` terminator in any
+    of the immediately nested regions of this op or
+    `RegionBranchPoint::parent()`. In the latter case, the branch originates
+    from outside of the op, i.e., when first executing this op.
 
     A "region successor" indicates the target of a branch. It can indicate
     either a region of this op or this op itself. In the former case, the region
@@ -141,6 +142,16 @@ def RegionBranchOpInterface : OpInterface<"RegionBranchOpInterface"> {
     results must have the same type. `areTypesCompatible` can be implemented to
     allow non-equal types.
 
+
+    Note: This interface works in conjunction with
+    `RegionBranchTerminatorOpInterface`. All immediately nested block
+    terminators that model branching between regions must implement the
+    `RegionBranchTerminatorOpInterface`. Otherwise, analyses/transformations
+    may miss control flow edges and produce incorrect results. Not every block
+    terminator is necessarily a region branch terminator: e.g., in the presence
+    of unstructured control flow, a block terminator could indicate a branch to
+    a 
diff erent block within the same region.
+
     Example:
 
     ```
@@ -206,7 +217,7 @@ def RegionBranchOpInterface : OpInterface<"RegionBranchOpInterface"> {
       }]
     >,
     InterfaceMethod<[{
-        Returns the potential region successors when branching from `point`.
+        Returns all potential region successors when branching from `point`.
         These are the regions that may be selected during the flow of control.
 
         When `point = RegionBranchPoint::parent()`, this method returns the
@@ -370,7 +381,14 @@ def RegionBranchTerminatorOpInterface :
   let description = [{
     This interface provides information for branching terminator operations
     in the presence of a parent `RegionBranchOpInterface` implementation. It
-    specifies which operands are passed to which successor region.
+    acts as a marker for valid region branch points and specifies which
+    operands are passed to which region successor.
+
+    Note: If an operation does not implement the
+    `RegionBranchTerminatorOpInterface`, then that op has no region successors.
+    (However, there may be other block terminators in the same region that
+    implement the `RegionBranchTerminatorOpInterface`, so the enclosing region
+    may have region successors.)
   }];
   let cppNamespace = "::mlir";
 


        


More information about the Mlir-commits mailing list