https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114041

--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Reduced testcase:

unsigned a[24], b[24];

__attribute__((noipa)) unsigned
foo (unsigned _BitInt(4) x)
{
  for (int i = 0; i < 24; ++i)
    a[i] = i;
  unsigned e = __builtin_stdc_bit_ceil (x);
  for (int i = 0; i < 24; ++i)
    b[i] = i;
  return e;
}

int
main ()
{
  if (foo (0) != 1)
    __builtin_abort ();
}

I have to confirm Andrew's comment, before the graphite dump there was
  if (x_14(D) > 1)
    goto <bb 5>; [59.00%]
  else
    goto <bb 11>; [41.00%]

  <bb 11> [local count: 17609365]:
  goto <bb 6>; [100.00%]

  <bb 5> [local count: 25340307]:
  _2 = x_14(D) + 15;
  _3 = (unsigned int) _2;
  _4 = __builtin_clz (_3);
  _5 = 31 - _4;
  _6 = 2 << _5;
  iftmp.1_15 = (unsigned int) _6;

  <bb 6> [local count: 42949672]:
  # iftmp.1_10 = PHI <iftmp.1_15(5), 1(11)>
This isn't part of any kind of loop, it is in between 2 different loops.
Graphite hoists some of the statements to bb 2 where it is unconditional:
  _32 = x_14(D) + 15;
  _33 = (unsigned int) _32;
the rest of it remains after the first loop, but is now unconditional:
  <bb 18> [count: 0]:
  _47 = 1;
  _31 = __builtin_clz (_33);
  _34 = 31 - _31;
  _35 = 2 << _34;
  iftmp.1_36 = (unsigned int) _35;
  _48 = iftmp.1_36;
  iftmp.1_37 = _48;
In the testcase x is 0, so __builtin_stdc_bit_ceil returns 1, but when we take
the > 1
path, it is 2 << (31 - 24) instead.
The above feels like what ifcvt would do, if that _47 in there stands for one
of the phi arguments and _48 for the other.  Except __builtin_clz invokes UB
when run on 0 (which is one of the reasons why it was guarded) and there is no
conditional merging at the end.

Reply via email to