https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117420
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> --- So, we have in ccp1 dump _2 = a.0_1 <= 0; # RANGE [irange] int [0, 1] MASK 0x1 VALUE 0x0 _3 = (int) _2; _4 = -_3; # RANGE [irange] int [-INF, +INF] MASK 0xfffffffe VALUE 0x1 _5 = _4 | 1; # RANGE [irange] int [-INF, +INF] MASK 0xfffffffe VALUE 0x1 b_9 = -_5; # RANGE [irange] int [-INF, +INF] MASK 0xfffffffe VALUE 0x0 _6 = ~b_9; # RANGE [irange] int [0, 0][2, 2] MASK 0x2 VALUE 0x0 _7 = _6 & 2; # RANGE [irange] int [0, 1] MASK 0x1 VALUE 0x0 c_10 = _7 / 2; if (b_9 != 1) and that looks reasonable to me. Depending on a.0_1 range all the SSA_NAMEs have 2 different values. a.0_1 [1,MAX] [MIN,0] _2 0 1 _3 0 1 _4 0 -1 _5 1 -1 b_9 -1 1 _6 0 -2 _7 0 2 c_10 0 1 (#c1 testcase). forwprop1 IMHO correctly optimizes b_9 != 1 to _5 != -1 both before and after the above mentioned commit; so - if (b_9 != 1) + if (_5 != -1) Before that commit it also optimized - # RANGE [irange] int [-INF, +INF] MASK 0xfffffffe VALUE 0x1 - b_9 = -_5; # RANGE [irange] int [-INF, +INF] MASK 0xfffffffe VALUE 0x0 - _6 = ~b_9; + _11 = _3 * -2; # RANGE [irange] int [0, 0][2, 2] MASK 0x2 VALUE 0x0 - _7 = _6 & 2; + _7 = _11 & 2; which is also correct, but with that commit onwards, it instead optimizes - # RANGE [irange] int [-INF, +INF] MASK 0xfffffffe VALUE 0x1 - b_9 = -_5; - # RANGE [irange] int [-INF, +INF] MASK 0xfffffffe VALUE 0x0 - _6 = ~b_9; - # RANGE [irange] int [0, 0][2, 2] MASK 0x2 VALUE 0x0 - _7 = _6 & 2; # RANGE [irange] int [0, 1] MASK 0x1 VALUE 0x0 - c_10 = _7 / 2; - if (b_9 != 1) + c_10 = -_3; and that looks incorrect to me. As written above, _3 is either 0 or 1 (the latter when a == 0 which is what the test checks), so if anything, it should be c_10 = _3; not c_10 = -3; which has range [-1, 0]. While c_10 is unused, I think it all goes downhill from this because the recorded range of c_10 doesn't match what value it will actually get and during fre1 that results in miscomputation of the _4 range, instead of [-1, 0] it gets [0, 1].