https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106511
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |missed-optimization --- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> --- The missed optimization is symTotal = 0; for (i = 0; i < 16; i++) { if (t&(1 << (15-i))) { k = get_bits(bd, 16); for (j = 0; j < 16; j++) if (k&(1 << (15-j))) symToByte[symTotal++] = (16*i)+j; } } ... symCount = symTotal+2; for (j = 0; j < groupCount; j++) { unsigned char length[258], temp[20 +1]; int minLen, maxLen, pp; # 235 "bunzip2.c" t = get_bits(bd, 5)-1; for (i = 0; i < symCount; i++) { ... length[i] = t+1; } minLen = maxLen = length[0]; to see that symCount cannot be zero and thus the loop header copy check for the loop on the last line can be elided. It looks quite obvious to me that should be able to compute a range for symTotal and thus symCount. SCEV is likely of not much help here but we should be able to compute the maximum number of times symTotal++ is executed by looking at the number of iterations of the loop nest. Note that with -O we do not run VRP and with -O2 we don't warn. But the testcase void link_error (); int bar (); void foo () { int symTotal = 0; for (int i = 0; i < 16; ++i) { if (bar()) symTotal++; } if (symTotal < 0 || symTotal > 16) link_error (); } shows that even with -O2 VRP only figures that symTotal is positive, it doesn't get the upper bound: <bb 6> [local count: 63136016]: # RANGE [irange] int [0, +INF] NONZERO 0x7fffffff # symTotal_19 = PHI <symTotal_3(5)> if (symTotal_19 > 16) given that loop header copying short-cuts the initialization of length[] it's clear that we diagnose the unconditional use after the loop.