In #168, we added LLVM dialect support for block addresses. Block addresses are modeled as a llvm.blocktag operation in the block whose address is taken, and the actual address obtained from llvm.blockaddress that refers to the tag.
The verifier requirement is that llvm.blockaddress must always have a corresponding llvm.blocktag. If the block containing this llvm.blocktag is not reachable, simplify-cfg may eliminate it, thus invalidating the verifier requirement.
Should we have an interface for conveying that certain blocks cannot be removed even if unreachable? MLIR doesn't seem to care.
// mlir-opt -canonicalize --mlir-print-ir-after-all addr_taken_block.mlir
module {
llvm.func @test_blockaddress() -> !llvm.ptr {
// 1. Get the address of the block tagged with id = 42
%addr = llvm.blockaddress <function = @test_blockaddress, tag = <id = 42>> : !llvm.ptr
// 2. Normal control flow exits the function immediately
llvm.return %addr : !llvm.ptr
// 3. This block is isolated from standard CFG successors/predecessors
^indirect_target:
llvm.blocktag <id = 42>
llvm.return %addr : !llvm.ptr
}
}
Running mlir-opt as commented above will result in the optimizer eliminating ^indirect_target, leading to a verifier failure later.
In #168, we added LLVM dialect support for block addresses. Block addresses are modeled as a
llvm.blocktagoperation in the block whose address is taken, and the actual address obtained fromllvm.blockaddressthat refers to the tag.The verifier requirement is that
llvm.blockaddressmust always have a correspondingllvm.blocktag. If the block containing thisllvm.blocktagis not reachable,simplify-cfgmay eliminate it, thus invalidating the verifier requirement.Should we have an interface for conveying that certain blocks cannot be removed even if unreachable? MLIR doesn't seem to care.
Running
mlir-optas commented above will result in the optimizer eliminating^indirect_target, leading to a verifier failure later.