https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108166
--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> --- The phiopt2 optimization is: # iftmp.3_10 = PHI <iftmp.3_14(3), 0(2)> - if (iftmp.3_10 != 0) - goto <bb 6>; [56.25%] - else - goto <bb 5>; [43.75%] - - <bb 5> [local count: 536870913]: - - <bb 6> [local count: 1073741824]: - # iftmp.2_9 = PHI <iftmp.3_10(4), 8(5)> - _4 = iftmp.2_9 < 0; + _4 = iftmp.3_10 < 0; So, we have _4 = (iftmp.3_10 ?: 8) < 0 and the optimization optimizes that to _4 = iftmp.3_10 < 0. If iftmp.3_10 is non-zero, then it is the same comparison, if iftmp.3_10 is zero, then previously we'd set _4 to 8 < 0 and newly set it to 0 < 0, both are false. The problem is in global ranges I think, previously we had: # RANGE [irange] int [-INF, -1][1, +INF] # iftmp.2_9 = PHI <iftmp.3_10(4), 8(5)> which is correct, it was iftmp.3_10 ?: 8 which is always non-zero. But this rnage is moved to iftmp.3_10 after the optimization: # RANGE [irange] int [-INF, -1][1, +INF] # iftmp.3_10 = PHI <iftmp.3_14(3), 0(2)> which is incorrect, we don't know anything about iftmp.3_10 range there because d is VARYING.