https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96015
--- Comment #12 from Jeffrey A. Law <law at redhat dot com> --- The block in question goes away because it serves no purpose: <bb 5> [local count: 242478389]: _13 = *self_11(D); _16 = *other_12(D); sign_17 = _13 - _16; if (sign_17 == 0) goto <bb 13>; [34.00%] else goto <bb 6>; [66.00%] <bb 6> [local count: 160035736]: goto <bb 13>; [100.00%] Note that bb6 just transfers control to bb13 with no other side effects. As a result bb5 is equivalent to: <bb 5> [local count: 242478389]: _13 = *self_11(D); _16 = *other_12(D); sign_17 = _13 - _16; if (sign_17 == 0) goto <bb 13>; [34.00%] else goto <bb 13>; [66.00%] With both arms of the conditional going to the same place and no other uses of sign_17 the whole block just turns into goto <bb13>; I see nothing wrong with what was done by DCE. The problem must be earlier in the optimizer pipeline.