[Mlir-commits] [mlir] [MLIR] Introduce support for early exits (PR #166688)
Mehdi Amini
llvmlistbot at llvm.org
Tue Mar 31 07:17:40 PDT 2026
================
----------------
joker-eph wrote:
> This is the key point: Why not discuss the merits of scf.while and how to address the same use with breaking control flow? Right now it seems you're adding a new op to do basically the same thing but in a different way.
It is true that early-exits are not introducing anything we can't already express with scf.while for example. However I would bring up two things:
1) Convenience: expressing code that is expressed with early-exit into a form that fits scf.while is not totally trivial. You need to carry over quite a significant amount of state and guards to emulate the same code-paths.
2) Analyses become less precise in general when you emulate this with scf.while style control-flow.
I added a test to illustrate this: https://github.com/joker-eph/llvm-project/blob/98db83bf57bc906399930abca36292307164dc42/mlir/test/Transforms/sccp-early-exit.mlir
I simplified as much as possible a test case I saw somewhere (I don't remember which DSL), here is the pseudo code:
```
a = 0
while (true) {
if (cond) {
a = -5;
return; // terminate the function
}
a++;
if (other_cond) {
break;
}
}
if (a < 0) {
do_something(); // actually dead code.
}
```
The question is how can the compiler realize that the `do_something` is dead code.
In MLIR SCF right now the code above would have to be something like (pseudo-code but no early exit):
```
a = 0
should_break = false
a, return_flag = while {
a_inner, return_flag_inner, should_break = if (cond) {
yield -5, true, true
} else {
yield a+1, false, true
}
scf.condition(should_break) iter_args(a_inner, return_flag_inner)
}
if (!return_flag) {
if (a < 0) {
do_something(); // actually dead code.
}
}
```
Now the problem here is that something like integer range analysis would kick in on the first example and allow to eliminate the `if (a < 0)`, but without the early exit we end-up approximating the return path as a live path and that confuses the analysis.
I don't know if we can recover this in other ways though (some code transformations exposing the original program structure?).
Note that flat CFGs don't have this problem they have natural "early exit" anytime.
https://github.com/llvm/llvm-project/pull/166688
More information about the Mlir-commits
mailing list