https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117243
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |hubicka at gcc dot gnu.org,
| |jakub at gcc dot gnu.org,
| |pinskia at gcc dot gnu.org,
| |rguenth at gcc dot gnu.org
--- Comment #10 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Cleaned up #c7:
void
foo (unsigned int a, unsigned char b)
{
lbl:
for (b = 0; b <= 7; b++)
{
unsigned char c[1][1];
int i, j;
for (i = 0; i < 1; i++)
for (j = 0; j < 1; j++)
c[i][j] = 1;
if (b)
goto lbl;
}
}
int
main ()
{
foo (1, 2);
}
The crash is because at cunroll time we decide to replace the loop by
__builtin_unreachable ().
And we do so because it sees clearly endless loop which has in loop structures
as upper bound of the number of iterations 8.
>From what I can see, starting with the end of ch2 pass, we have
<bb 2> [local count: 2657777]:
<bb 3> [local count: 268435456]:
lbl:
<bb 4> [local count: 536870912]:
# b_1 = PHI <0(3), 1(4)>
if (b_1 != 0)
goto <bb 3>; [50.00%]
else
goto <bb 4>; [50.00%]
where the innermost loop is just bb 4 and has 8 as upper bound (it comes
originally from the b = 0; b <= 7; b++ loop) and then there is an outer loop
with bb3 and bb4 which doesn't have bounded iterations.
Before phiopt3 it is still:
Loops in function: foo
loop_0 (header = 0, latch = 1)
{
bb_2 (preds = {bb_0 }, succs = {bb_3 })
{
<bb 2> [local count: 2657777]:
}
loop_1 (header = 3, latch = 4
iterations by profile: 99.999992 (unreliable, maybe flat) entry count:2657777
(estimated locally, freq 1.0000))
{
bb_3 (preds = {bb_2 bb_4 }, succs = {bb_4 })
{
<bb 3> [local count: 268435456]:
lbl:
}
loop_2 (header = 4, latch = 4, finite_p
upper_bound 8
likely_upper_bound 8
iterations by profile: 1.000000 (unreliable, maybe flat) entry
count:268435456 (estimated locally, freq 101.0000))
{
bb_4 (preds = {bb_3 bb_4 }, succs = {bb_3 bb_4 })
{
<bb 4> [local count: 536870912]:
# b_1 = PHI <0(3), 1(4)>
if (b_1 != 0)
goto <bb 3>; [50.00%]
else
goto <bb 4>; [50.00%]
}
}
}
}
which looks correct to me (8 is way too large, that loop loops just once).
Phiopt itself then just changes that
# b_1 = PHI <0(3), 1(4)>
if (b_1 != 0)
to
# b_1 = PHI <0(3), _5(4)>
_5 = b_1 ^ 1;
if (0 != 0)
Then phiopt (well, seems TODO_cleanup_cfg at the end of it) decides to merge
the 2 blocks:
<bb 2> [local count: 2657777]:
<bb 3> [local count: 536870912]:
# b_1 = PHI <0(2), _5(3)>
_5 = b_1 ^ 1;
goto <bb 3>; [100.00%]
but doesn't adjust appropriately the loop structures:
Loops in function: foo
loop_0 (header = 0, latch = 1)
{
bb_2 (preds = {bb_0 }, succs = {bb_3 })
{
<bb 2> [local count: 2657777]:
}
loop_2 (header = 3, latch = 3, finite_p
upper_bound 8
likely_upper_bound 8
iterations by profile: 200.999984 (unreliable) entry count:2657777 (estimated
locally, freq 1.0000))
{
bb_3 (preds = {bb_2 bb_3 }, succs = {bb_3 })
{
<bb 3> [local count: 536870912]:
# b_1 = PHI <0(2), _5(3)>
_5 = b_1 ^ 1;
goto <bb 3>; [100.00%]
}
}
}
which is wrong, because the inner loop is infinite, not finite_p and doesn't
have upper_bound of 8.
Though, I'm afraid I have no idea what should adjust the loop structures here,
whether already phiopt itself which turns the conditional branch into
unconditional, or the following cfgcleanup.