https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84321

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Less reduced testcase so that it is valid:

int c;

void
foo (int *a, int b)
{
  int e;
  if (b == 1)
    return -1;
  for (e = 0; e < (b & ~7); e += 8)
    ;
  for (++e; e < b;)
    c = a[e];
}

This is because the range info and nonzero bits improvements improve just
gradually and improvements on nonzero bits don't have immediate effect on the
min/max.
We initially have:
  # RANGE [-2147483648, 2147483647] NONZERO 4294967288
  # e_11 = PHI <e_6(4)>
  # RANGE [-2147483648, 2147483647] NONZERO 4294967289
  e_13 = e_11 + 1;
i.e. basically all range, but 0xfffffff8 and 0xfffffff9 masks.
Then vrp1 improves that to:
  # RANGE [0, 2147483647] NONZERO 2147483640
  # e_11 = PHI <e_6(4)>
  # RANGE ~[-2147483647, 0] NONZERO 4294967289
  e_13 = e_11 + 1;
which is conservatively correct, but not perfect, because of the 0x7fffffff8
nonzero mask on the PHI guarantees that the actual range must be
[0, 2147483640].  And because e_11 is never INT_MAX, e_11 + 1 will never be
INT_MIN.  Later on ccp3 improves it further:
  # RANGE [0, 2147483647] NONZERO 2147483640
  # e_18 = PHI <e_12(4), 0(3)>
  # RANGE ~[-2147483647, 0] NONZERO 2147483641
  e_13 = e_18 + 1;
but just the nonzero mask.
So, while it would be nice to optimize this better, the asserts in
intersect_range_with_nonzero_bits are just wrong, just punt (return
VR_UNDEFINED) in those cases.

Reply via email to