[mlir] Only conditionally lower CF branching ops to LLVM
authorTres Popp <tpopp@google.com>
Tue, 2 Aug 2022 08:18:52 +0000 (10:18 +0200)
committerTres Popp <tpopp@google.com>
Thu, 4 Aug 2022 14:36:27 +0000 (16:36 +0200)
commit448adfee05b737a26dda34e7ae2cd4948760fff0
tree4adb7cfccbdf4ddbaeb37c4c55a3d1f3630b31ac
parentd0541b47000739c68c540170c6b9790ec1ea3b77
[mlir] Only conditionally lower CF branching ops to LLVM

Previously cf.br cf.cond_br and cf.switch always lowered to their LLVM
equivalents. These ops are all ops that take in some values of given
types and jump to other blocks with argument lists of the same types. If
the types are not the same, a verification failure will later occur. This led
to confusions, as everything works when func->llvm and cf->llvm lowering
both occur because func->llvm updates the blocks and argument lists
while cf->llvm updates the branching ops. Without func->llvm though,
there will potentially be a type mismatch.

This change now only lowers the CF ops if they will later pass
verification. This is possible because the parent op and its blocks will
be updated before the contained branching ops, so they can test their
new operand types against the types of the blocks they jump to.

Another plan was to have func->llvm only update the entry block
signature and to allow cf->llvm to update all other blocks, but this had
2 problems:
1. This would create a FuncOp lowering in cf->llvm lowering which is
   awkward
2. This new pattern would only be applied if the containing FuncOp is
   marked invalid. This is infeasible with the shared LLVM type
   conversion/target infrastructure.

See previous discussions at
https://discourse.llvm.org/t/lowering-cf-to-llvm/63863 and
https://github.com/llvm/llvm-project/issues/55301

Differential Revision: https://reviews.llvm.org/D130971
mlir/docs/TargetLLVMIR.md
mlir/lib/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.cpp
mlir/test/Conversion/ControlFlowToLLVM/invalid.mlir [new file with mode: 0644]