https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123300
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jakub at gcc dot gnu.org
--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Slightly cleaned up:
[[gnu::noipa]] void
bar (int a, int b)
{
if (a < 0)
__builtin_abort ();
}
[[gnu::noipa]] void
foo (int n, bool p)
{
for (int i = n; i-- > 0;)
{
const int x = 1 << i;
if (x <= 0)
__builtin_unreachable ();
if (p)
bar (i, x);
}
}
int
main ()
{
foo (4, true);
}
This goes at -O2 wrong during vrp1. Before that we have correct:
<bb 2> [local count: 118111600]:
goto <bb 10>; [100.00%]
...
<bb 10> [local count: 1073741824]:
# i_2 = PHI <i_1(9), n_4(D)(2)>
# RANGE [irange] int [-INF, 2147483646]
i_7 = i_2 + -1;
if (i_2 > 0)
goto <bb 3>; [89.00%]
else
goto <bb 8>; [11.00%]
n_4(D) can be be any integer, so [-INF, 2147483646] is the right range for that
minus 1.
But vrp1 turns that into
<bb 2> [local count: 118111600]:
goto <bb 5>; [100.00%]
<bb 3> [local count: 955630224]:
# RANGE [irange] const int [1, +INF]
x_8 = 1 << i_7;
if (p_9(D) != 0)
goto <bb 4>; [33.00%]
else
goto <bb 5>; [67.00%]
<bb 4> [local count: 315357972]:
# USE = nonlocal escaped
# CLB = nonlocal escaped
bar (i_7, x_8);
<bb 5> [local count: 1073741824]:
# i_2 = PHI <i_7(3), n_4(D)(2), i_7(4)>
# RANGE [irange] int [0, 2147483646]
i_7 = i_2 + -1;
if (i_2 > 0)
goto <bb 3>; [89.00%]
else
goto <bb 6>; [11.00%]
<bb 6> [local count: 118111600]:
return;
where the recorded range for i_7 is wrong, n_4(D) can still be anything there,
and even when not counting the n <= 0 case (but it has to be counted until ch
adds the if (n <= 0) return; conditional), it would at least have to include -1
as valid value, the loop iterates in the
example with i_7 3, 2, 1, 0 and at the end of the bar (0, 1); iteration i_2 is
0 and i_7 is -1.