https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125291
--- Comment #3 from Xi Ruoyao <xry111 at gcc dot gnu.org> ---
Before vrp2:
unsigned char flagbits;
... ...
_877 = flagbits_832 + 254;
_879 = (int) _877;
... ...
# prephitmp_880 = PHI <_879(40), 6(41)>
... ...
_68 = (int) flagbyte_254;
_70 = _68 >> prephitmp_880;
_71 = _70 & 3;
and vrp2 does:
Global Exported: flagbits_832 = [irange] unsigned char [0, 0][2, 2][4, 4][6, 6]
MASK 0x6 VALUE 0x0
Global Exported: _877 = [irange] unsigned char [0, 0][2, 2][4, 4] MASK 0x6
VALUE 0x0
Global Exported: _879 = [irange] int [0, 0][2, 2][4, 4] MASK 0x6 VALUE 0x0
all correct but then
Global Exported: prephitmp_880 = [irange] int [6, 6] MASK 0x0 VALUE 0x6
What happens here seems (u8)[6, 260, 514] is peeled to [6, 260, 514], as
scev_probably_wraps_p isn't supposed to catch (u8)[6, 260, 514] because we
really don't want to consider "for (u8 i = 6; i > 0; i -= 2)" "wrapping."
Then VRP uses the intersect of {2, 4, 6} and {6, 260, 514} as the value range,
which is {6}, so prephitmp_880 is incorrectly replaced with the constant 6.