[mlir] Fix block merging with the result of a terminator
authorMarkus Böck <markus.boeck02@gmail.com>
Mon, 21 Mar 2022 12:26:00 +0000 (13:26 +0100)
committerMarkus Böck <markus.boeck02@gmail.com>
Mon, 21 Mar 2022 12:26:35 +0000 (13:26 +0100)
commitc14ba3c4be09348cb5e796d000bfa62fba931ae8
tree707fc267da296125f32b06bb53302587e4953067
parent8ee1ef2a087da1a101a6b2c0bea31788da289e0b
[mlir] Fix block merging with the result of a terminator

When the current implementation merges two blocks that have operands defined outside of their block respectively, it will merge these by adding a block argument in the resulting merged block and adding successor arguments to the predecessors.
There is a special case where this is incorrect however: If one of predecessors terminator produce the operand, inserting the block argument and updating the predecessor would lead to the terminator using its own result as successor argument.
IR Example:
```
  %0 = "test.producing_br"()[^bb1, ^bb2] {
        operand_segment_sizes = dense<0> : vector<2 x i32>
} : () -> i32

^bb1:
  "test.br"(%0)[^bb4] : (i32) -> ()
```
where `^bb1` is then merged with another block would lead to:
 ```
  %0 = "test.producing_br"(%0)[^bb1, ^bb2]
```

This patch fixes that issue during clustering by making sure that if the operand is from an outside block, that it is not produced by the terminator of a predecessor.

Differential Revision: https://reviews.llvm.org/D121988
mlir/lib/Transforms/Utils/RegionUtils.cpp
mlir/test/Transforms/canonicalize-block-merge.mlir
mlir/test/lib/Dialect/Test/TestDialect.cpp
mlir/test/lib/Dialect/Test/TestOps.td