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].