This is an archive of the discontinued LLVM Phabricator instance.

[mlir] Only conditionally lower CF branching ops to LLVM
ClosedPublic

Authored by tpopp on Aug 2 2022, 1:32 AM.

Details

Summary

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

Diff Detail

Event Timeline

tpopp created this revision.Aug 2 2022, 1:32 AM
tpopp requested review of this revision.Aug 2 2022, 1:32 AM
rriddle added inline comments.Aug 2 2022, 1:36 AM
mlir/lib/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.cpp
79

Please use static functions instead of anonymous namespaces.

99

notifyMatchFailure has an overload that takes a functor of a diagnostic. That can be used instead of using raw_string_ostream: https://github.com/llvm/llvm-project/blob/b586dc21a7e8154a20fdf99da231c79dd762048f/mlir/examples/toy/Ch5/mlir/LowerToAffineLoops.cpp#L220

140

Please use the global "failed(...)" function instead of the method on these.

ftynse added a comment.Aug 2 2022, 1:47 AM

Thanks! I think this is better than the current state because it at least gives the useful hint in the debug output. It would be nice to document the required pass ordering somewhere, maybe in https://mlir.llvm.org/docs/TargetLLVMIR/#conversion-to-the-llvm-dialect.

mlir/lib/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.cpp
76

Nit: triple-slash comments for top-level entries plz.

83

Nit: MLIR uses camelCase for variable names.

84

Nit: please expand auto unless the type is obvious from this statement alone.

88

This condition doesn't match the error message: the condition checks that the remapped value is produced by an op (I suppose the intention is to check if it is produced by a cast), but the message is about type mismatch. Depending on the type converter setup, we can end up in a situation where types actually match but the condition is still true.

93

Nit: operator << is overloaded for IR types IIRC, so it is possible to do rsos << operandType

tpopp updated this revision to Diff 449960.Aug 4 2022, 6:53 AM
tpopp marked 7 inline comments as done.

Respond to style fixes and improve the unrealized_conversion_cast conditional.

tpopp marked an inline comment as done.Aug 4 2022, 6:53 AM
ftynse accepted this revision.Aug 4 2022, 6:59 AM
ftynse added inline comments.
mlir/lib/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.cpp
82

Nit: I think clang-tidy would suggest a const & here

163

Same as above.

This revision is now accepted and ready to land.Aug 4 2022, 6:59 AM
tpopp marked 2 inline comments as done.Aug 4 2022, 7:35 AM
This revision was landed with ongoing or failed builds.Aug 4 2022, 7:37 AM
This revision was automatically updated to reflect the committed changes.