https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78969
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> --- This is because the PHI at that point is only created during CFG changes at the end of VRP1 pass. After creating ASSERT_EXPRs, we still have: <bb 2> [1.00%]: goto <bb 4>; [100.00%] <bb 3> [99.00%]: # RANGE [0, 1000] NONZERO 1023 idx_7 = ASSERT_EXPR <idx_1, idx_1 <= 999>; __builtin_snprintf (p_4(D), 4, "%d", idx_7); # RANGE [1, 1000] NONZERO 1023 idx_6 = idx_7 + 1; <bb 4> [100.00%]: # RANGE [0, 1000] NONZERO 1023 # idx_1 = PHI <0(2), idx_6(3)> if (idx_1 <= 999) goto <bb 3>; [99.00%] else goto <bb 5>; [1.00%] <bb 5> [1.00%]: return; Then VRP1 correctly determines: idx_1: [0, 1000] .MEM_2: VARYING idx_6: [1, 1000] idx_7: [0, 999] EQUIVALENCES: { idx_1 } (1 elements) then the ASSERT_EXPRs are removed, which means whenever idx_7 is used we now use idx_1, and finally the loop is changed, idx_8 and idx_10 is created: <bb 2> [1.00%]: goto <bb 6>; [100.00%] <bb 3> [99.00%]: # RANGE [0, 1000] NONZERO 1023 # idx_10 = PHI <idx_1(4), idx_8(6)> __builtin_snprintf (p_4(D), 4, "%d", idx_10); # RANGE [1, 1000] NONZERO 1023 idx_6 = idx_10 + 1; <bb 4> [99.00%]: # RANGE [0, 1000] NONZERO 1023 # idx_1 = PHI <idx_6(3)> if (idx_1 != 1000) goto <bb 3>; [98.99%] else goto <bb 5>; [1.01%] <bb 5> [1.00%]: return; <bb 6> [1.00%]: # RANGE [0, 1000] NONZERO 1023 # idx_8 = PHI <0(2)> goto <bb 3>; [100.00%] But there is no obvious connection between idx_10 (which indeed nicely could hold the [0, 999] range) and idx_7 (the already removed ASSERT_EXPR); similarly, idx_8 could very well have RANGE [0, 0] but doesn't (though in that case it isn't that big a deal, because it is going to be removed immediately afterwards).