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.

Reply via email to