[Mlir-commits] [mlir] [MLIR][LLVM] Support for indirectbr (PR #135092)
Tobias Gysi
llvmlistbot at llvm.org
Thu Apr 10 23:10:19 PDT 2025
================
@@ -1705,6 +1705,65 @@ def LLVM_BlockTagOp : LLVM_Op<"blocktag"> {
let hasVerifier = 0;
}
+//===----------------------------------------------------------------------===//
+// IndirectBrOp
+//===----------------------------------------------------------------------===//
+
+def LLVM_IndirectBrOp : LLVM_TerminatorOp<"indirectbr",
+ [SameVariadicOperandSize, DeclareOpInterfaceMethods<BranchOpInterface>,
+ Pure]> {
+ let description = [{
+ Transfer control flow to address in `$addr`. A list of possible target
+ blocks in `$successors` can be provided and maybe used as a hint in LLVM:
----------------
gysit wrote:
> All possible destination blocks must be listed in the label list, otherwise this instruction has undefined behavior.
Ok good to know, that means there is at least the intent to list all possible successors :).
> Otherwise, maybe change llvm.blocktag verifier to not allow it in unrecheable blocks?
Yes that may make sense to catch at least some cases. And maybe we want to comment in the doc of indirect branch op that running region simplify can result in deleting bock tags and invalid IR.
It does indeed look like `mlir::eraseUnreachableBlocks` cannot be influence from the dialect. That would require some kind of interface on the block terminator op. Another solution could be to have some dummy edge between ,for example, the entry block and all blocks that contain a tag:
```
llvm.func @fn(%dest : !llvm.ptr, %arg0 : i32, %arg1 : i32) -> i32 {
^entry:
// This op always jumps to ^old_entry adds edges to all block that require an id.
llvm.block_tags ^old_entry [
^head <id = 0>
^tail <id = 1>
]
^old_entry:
llvm.indirectbr %dest : !llvm.ptr, [
^head
]
^head:
llvm.return %arg0 : i32
^tail:
llvm.return %arg1 : i32
}
```
This solution needs an artificial entry block though which may result in other problems. Some operations such as allocas should typically be in the entry block etc. Additionally the terminator probably requires branch arguments for all successors even if it never takes the edge.
So given that the problematic case is ub we can maybe just live with an additional verifier and a comment that running region simplify is dangerous in the presence of indirect branch? What happens in the export to LLVM IR if a blocktag got deleted?
https://github.com/llvm/llvm-project/pull/135092
More information about the Mlir-commits
mailing list