https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106112
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Assignee|unassigned at gcc dot gnu.org |rguenth at gcc dot gnu.org Status|NEW |ASSIGNED --- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- <bb 2> [local count: 1073741824]: e.0_1 = e; _2 = e.0_1 | 4294967292; e = _2; d.1_3 = d; _4 = (long unsigned int) d.1_3; - # RANGE [2147483647, 6442450942] NONZERO 8589934591 + # RANGE ~[2147483647, 18446744071562067967] _10 = _4 + 4294967295; _7 = _10 - _2; _8 = 18446744073709551615 % _7; _9 = (int) _8; c = _9; _11 = 18446744073709551614 - _2; - _13 = d.1_3 + -1; - # RANGE ~[2147483647, 18446744071562067967] - _14 = (long unsigned int) _13; - _15 = _11 % _14; + _15 = _11 % _10; is the key change, replacing (unsigned long)(intvar + -1) with (unsigned long)intvar + 4294967295 It looks like /* For constants simply extend it. */ if (TREE_CODE (op) == INTEGER_CST) return wide_int_to_tree (wide_type, wi::to_wide (op)); doesn't sign-extend the -1 from int to unsigned log. Using wi::to_widest does and fixes the testcase.