Control flow optimisations duplicate blocks
During work on #8275 (closed) I observed that control flow optimisation pass in the Cmm pipeline duplicates block that does the stack check, which is completely redundant. There is at least one bug in !CmmContFlowOpt module. Consider this:
L1: goto L2 L2: whatever L3: goto L1
We are processing blocks from the end. When we reach L3 first guard in
maybe_concat function (!CmmContFlowOpt.hs, line 123) will turn that blocks into:
L1: goto L2 L2: whatever L3: goto L2
However, the number of predecessors of L2 block is not updated because
backEdges is computed once before we run
maybe_concat and is not updated when we make changes to the block structure.
Another issue, which I have not yet encountered in practice but I believe may arise as well, comes from the fact that we may map one label to a different one, but again we don't that take into account when determining the number of predecessors.