https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90257
--- Comment #9 from Jakub Jelinek <jakub at gcc dot gnu.org> --- I believe the difference is caused by cfg cleanup without the noop move considering (code_label 34 6 37 9 1 (nil) [2 uses]) (note 37 34 36 9 [bb 9] NOTE_INSN_BASIC_BLOCK) (insn 36 37 53 9 (use (reg/i:DI 0 ax)) "pr90178.c":8:1 -1 (nil)) basic block a forwarder block (that seems correct), while with the noop it isn't and thus doesn't try to optimize it. The condition in try_forward_edges is: if (FORWARDER_BLOCK_P (target) && single_succ (target) != EXIT_BLOCK_PTR_FOR_FN (cfun)) and so it already tries to avoid changing forwarders to exit that way. But the single_succ of target is not EXIT, but an empty forwarder block to EXIT: (note 53 36 51 10 [bb 10] NOTE_INSN_BASIC_BLOCK) created by mode-switching.c (create_pre_exit). Wonder if the correct fix for PR90257 isn't extend the above test to also consider further forwarders to exit in the above test.