https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104639
--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> --- The ranger itself can't, i_2(D) in the PHI arg is ~[4, 4], and _3 is still [0, 1] aka VARYING. Yes, phiopt could handle this by seeing a PHI result is only used in an equality comparison and try to figure out something for it using range info or so, or vrp2 could. In GCC 11, it was indeed PRE that optimized that: if (i_2(D) == 4) goto <bb 4>; [97.00%] else goto <bb 3>; [3.00%] <bb 3> [local count: 3540129]: <bb 4> [local count: 118111600]: # i_6 = PHI <i_2(D)(3), 6(2)> _3 = i_6 != 0; which is what we have on the trunk until optimized with: _Bool _1; _Bool prephitmp_7; <bb 2> [local count: 118111600]: if (i_2(D) == 4) goto <bb 4>; [97.00%] else goto <bb 3>; [3.00%] <bb 3> [local count: 3540129]: _1 = i_2(D) != 0; <bb 4> [local count: 118111600]: # i_6 = PHI <i_2(D)(3), 6(2)> # prephitmp_7 = PHI <_1(3), 1(2)> and later reassoc2 optimizes that to just _6 = i_2(D) != 0; return _6;