[Mlir-commits] [mlir] [mlir][Analysis][NFC] Improve `RegionBranchOpInterface` API usage (PR #173983)
Matthias Springer
llvmlistbot at llvm.org
Wed Jan 7 04:35:44 PST 2026
================
@@ -115,8 +69,11 @@ mlir::getControlFlowPredecessors(Value value) {
return std::nullopt;
// Add the control flow predecessor operands to the work list.
RegionSuccessor region(regionOp, regionOp->getResults());
- SmallVector<Value> predecessorOperands = getRegionPredecessorOperands(
- regionOp, region, opResult.getResultNumber());
+ SmallVector<Value> predecessorOperands;
+ // TODO: This assumes that there are no non-forwarded op results in front
+ // of the forwarded op results.
----------------
matthias-springer wrote:
Sorry, the right term is "successor input". I updated the comment.
The second parameter of `getPredecessorValue` indexes into `getEntrySuccessorOperands` /`getSuccessorOperands`. The indexing starts with `0`. The problem here is that we are simply taking the op result number.
For example, let's assume that `scf.for` returns an additional value that is not related to an init_arg. Let's say it returns the number of iterations. (It does not really make sense to design the op like that, this is just for illustration purposes.)
```
%num_iter, %loop_carried = scf.for ... iter_args(%arg0 = %0) { ... }
// ^^^^^^^^^^^^^
// op result 1
```
Now we are calling `getControlFlowPredecessors(%loop_carried)` here. This will call `regionBranchOp.getPredecessorValues(..., 1, ...)`, which cause an out-of-bounds array access inside of `getPredecessorValues`. (The same thing happens with the original implementation before this PR.)
While we may not have such ops (at least in upstream MLIR) at the moment, the `RegionBranchOpInterface` allows them.
https://github.com/llvm/llvm-project/pull/173983
More information about the Mlir-commits
mailing list