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.