https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81165
--- Comment #8 from Alexandre Oliva <aoliva at gcc dot gnu.org> --- It is combine that simplifies a compare of _9 (aka t1) with 1: it knows _9 is either -1 or 0 from the &1 followed by -1, so it can't be equal to 1. From that simplification, others follow, and the loop exit test becomes a dead computation that is eventually removed. With the trunk, modified to disregard the 3rd argument to find_leader_in_sets, we figure that out in gimple, in forwprop4, and eliminate the compare with 1. We only realize both branches of the out-of-loop test end up at the same spot after removing an unused assigned in one of the branches, later on, in dce7, at which point the entire loop entry test becomes dead computation, but it lives on all the way to rtl cse1. With unmodified trunk, we introduce a new phi node at the merge after the initial if statement, at the loop entry test, standing for (int)t1, and this node seems to be what prevents the duplication of the loop entry block by dom3: the node is used within the loop body (it's what gets compared with 1 to decide whether or not the loop body traps). Without this duplication, we fail to simplify the test because we don't know enough about t1 to enable simplification. We'd have to keep separate (or split) the two paths out of the if statement to be able to optimize it, or have some means to represent that t1 can only hold the values -1, 0, or 2, not 1.