https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99101
--- Comment #20 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Michael Matz from comment #19) > (In reply to Michael Matz from comment #18) > > But there are other blocks control dependend on bb4, namely bb5 and bb9. > > To see this observe that bb9 doesn't pdom bb4, but there's a path from bb4 > > to > > bb9 (e.g. bb4 -> bb5 -> bb9), where one node in that path that isn't bb4 is > > ... where _each_ node in that path that isn't bb4 ... Sorry. > > (Essentially this captures the idea that the path-start node that is the > control > node is the _latest_ node that determines (non)execution of the path-end, > i.e. all > further nodes after the control node unavoidably pass through path-end). Yes, bb5 and bb9 are control dependent on bb4. But nothing in bb5 or bb9 ends up necessary (so the IV 'i' is elminated as well). We start with obviously necessary stmts Marking useful stmt: __builtin_puts (&"1"[0]); Marking useful stmt: xx.0_1 ={v} xx; Marking useful stmt: __builtin_abort (); And the only thing we deem necessary is Marking useful stmt: if (xx.0_1 != 0) because we mark this due to the self control-dependence of bb6 to itself when processing the necessary call. If we didn't do that we'd end up optimizing the testcase to just int main() { __builtin_puts ("1"); xx; abort (); } hmm, actually when removing the if (xx) stmt we end up redirecting the incoming edge to the loop latch and so we'd produce <bb 3> : __builtin_puts (&"1"[0]); xx.0_1 ={v} xx; goto <bb 3>; [100.00%] because we're using yet another idea of post-dominance, that by inverted_post_order_compute and it's kludge how to handle backwards unreachable blocks ... (it produces 7, 5, 9, 0, 2, 12, 3, 11, 4, 6, 1) At one point the code used to walk immediate post-dominators. This was changed for PR65337 in g:e4dbb0d449e778bc810d0d627a5aaefd0d7847b1