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.

Reply via email to