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.
(Note: The tests use "test.br" instead of cf.br to avoid other canonicalizations changing the IR and not causing the block merging)
Can we remove the mlir:: here?