https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85175
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Last reconfirmed| |2018-04-03 CC| |jakub at gcc dot gnu.org Ever confirmed|0 |1 --- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> --- The problem is that i is addressable, so it is not in SSA form. With -O2, the ch pass copies the loop header and so we end up with a PHI and in vrp2 (not vrp1!) we finally manage to compute the value range for the sprintf argument SSA_NAME; it is not precise, because we compute # RANGE [-2147483647, 3] # i.2_15 = PHI <0(2), _2(3)> because we really don't track what the addressable i contains and have: i.1_1 = i; # RANGE [-2147483647, 2147483647] _2 = i.1_1 + 1; i = _2; if (_2 <= 3) With -Os, there is no loop header copying and i.2_3 = i; if (i.2_3 <= 3) goto <bb 3>; [89.00%] is used directly in the sprintf, so there is no second SSA_NAME we could attach at least the limited [-2147483647, 3] range to. So, either the planned on-demand VR computation could help here, or perhaps some range splitting on GIMPLE, e.g. we could figure out that the taking of the address is dominated by large enough block (even loop here) where we could promote the variable into SSA form and only store it into the addressable var before the address is taken. If we do something like that, we'd need to add debug stmts.