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

ktkachov at gcc dot gnu.org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ktkachov at gcc dot gnu.org
   Last reconfirmed|                            |2026-10-20
             Status|UNCONFIRMED                 |NEW
     Ever confirmed|0                           |1

--- Comment #6 from ktkachov at gcc dot gnu.org ---
Reduced testcase aborts at -O3 on aarch64:


#define N 64

/* The counting exit is tested before the early exit, so the loop body runs
   one time less than the loop header.  The vector loop must not process a
   lane for the iteration that only tests the counter, as that lane reads the
   element next to the arrays.  */

__attribute__ ((noipa)) int
differs (const long *a, const long *b, unsigned long n)
{
  while (n != 0)
    {
      n--;
      if (a[n] != b[n])
       return 1;
    }
  return 0;
}
__attribute__ ((noipa)) int
differs_signed (const long *a, const long *b, long n)
{
  if (n < 0)
    return 2;
  while (--n >= 0)
    {
      if (a[n] != b[n])
       return 1;
    }
  return 0;
}

__attribute__ ((noipa)) int
differs_up (const long *a, const long *b, unsigned long n)
{
  unsigned long i = 0;
  while (i != n)
    {
      unsigned long j = i;
      i++;
      if (a[j] != b[j])
       return 1;
    }
  return 0;
}

/* The store before the early exit must not write the extra lane and must run
   once for every element.  */

__attribute__ ((noipa)) int
bump (const long *restrict a, const long *restrict b, long *restrict c,
      unsigned long n)
{
  while (n != 0)
    {
      n--;
      c[n] += 1;
      if (a[n] != b[n])
       return 1;
    }
  return 0;
}
static long abuf[N + 16] __attribute__ ((aligned (64)));
static long bbuf[N + 16] __attribute__ ((aligned (64)));
static long cbuf[N + 16] __attribute__ ((aligned (64)));

int
main (void)
{

  for (unsigned long n = 0; n <= N; n++)
    for (int off = 0; off < 8; off++)
      {
       /* Start the arrays at every alignment of a 64 byte vector and give
          the elements around them different values.  */
       long *a = abuf + 8 + off;
       long *b = bbuf + 8 + off;
       long *c = cbuf + 8 + off;
       for (unsigned long i = 0; i < n; i++)
         a[i] = b[i] = c[i] = i * 3 + 1;
       a[-1] = 1;
       b[-1] = 2;
       c[-1] = 5;
       a[n] = 3;
       b[n] = 4;
       c[n] = 6;

       if (differs (a, b, n) != 0 || differs_signed (a, b, n) != 0
           || differs_up (a, b, n) != 0)
         __builtin_abort ();

       if (bump (a, b, c, n) != 0 || c[-1] != 5 || c[n] != 6)
         __builtin_abort ();
       for (unsigned long i = 0; i < n; i++)
         if (c[i] != i * 3 + 2)
           __builtin_abort ();

       if (n > 0)
         {
           b[n / 2]++;
           if (differs (a, b, n) != 1 || differs_signed (a, b, n) != 1
               || differs_up (a, b, n) != 1)
             __builtin_abort ();
         }
      }

  return 0;
}

Reply via email to