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

--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> ---
OK, so it seems the runtime alias check is hosed.

merged alias checks:
  reference:      MEM[(const struct _Vector_impl_data &)_254]._M_start vs.
MEM[(struct _Vector_impl_data *)_256]._M_start
  segment length: 18446744073709551592(OVF)
  access size:    24
  alignment:      8
  flags:          WAR WAW ARBITRARY

that's a segment length of -24.  The loop in question looks like

  <bb 20> [local count: 347248109]:
  # __i_373 = PHI <0(89), __i_263(98)>
  # __p$_M_current_374 = PHI <_251(89), _254(98)>
  # __q$_M_current_5 = PHI <_247(89), _256(98)>
  _254 = __p$_M_current_374 + 18446744073709551592;
  _256 = __q$_M_current_5 + 18446744073709551592;
  _257 = MEM[(const struct _Vector_impl_data &)_254]._M_start;
  _258 = MEM[(const struct _Vector_impl_data &)_254]._M_finish;
  _259 = MEM[(const struct _Vector_impl_data &)_254]._M_end_of_storage;
  _260 = MEM[(const struct _Vector_impl_data &)_256]._M_start;
  MEM[(struct _Vector_impl_data *)_254]._M_start = _260;
  _261 = MEM[(const struct _Vector_impl_data &)_256]._M_finish;
  MEM[(struct _Vector_impl_data *)_254]._M_finish = _261;
  _262 = MEM[(const struct _Vector_impl_data &)_256]._M_end_of_storage;
  MEM[(struct _Vector_impl_data *)_254]._M_end_of_storage = _262;
  MEM[(struct _Vector_impl_data *)_256]._M_start = _257;
  MEM[(struct _Vector_impl_data *)_256]._M_finish = _258;
  MEM[(struct _Vector_impl_data *)_256]._M_end_of_storage = _259;
  __i_263 = __i_373 + 1;
  if (__k_225 <= __i_263)
    goto <bb 102>; [11.00%]
  else
    goto <bb 98>; [89.00%]

which looks like backwards walking swap of two arrays.

C testcase:

void __attribute__((noipa))
foo (long *a, int off, int n)
{
  for (int i = 0; i < n; ++i)
    {
      long tem1 = a[0];
      long tem2 = a[1];
      long tem3 = a[2]; 
      long tem4 = a[off + 1];
      a[0] = tem4;
      long tem5 = a[off + 2];
      a[1] = tem5;
      long tem6 = a[off + 3];
      a[2] = tem6; 
      a[off + 1] = tem1;
      a[off + 2] = tem2;
      a[off + 3] = tem3;
      a -= 3;
    }
}

int main ()
{
  long a[3 * 8];
  for (int i = 0; i < 3 * 8; ++i)
    a[i] = i;
  foo (a + 3 * 5, 6-1, 5);
  const long b[3 * 8] = { 0, 1, 2, 21, 22, 23, 18, 19, 20, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17 };
  for (int i = 0; i < 3 * 8; ++i)
    if (a[i] != b[i])
      __builtin_abort ();
}

Reply via email to