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

            Bug ID: 126587
           Summary: [15/16/17 Regression] Wrong code with vectorisation
                    (vect_preserves_scalar_order_p ?)
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ktkachov at gcc dot gnu.org
  Target Milestone: ---

/* Wrong code with -O3 on aarch64.

   vect_preserves_scalar_order_p (gcc/tree-vect-data-refs.cc:297-306) returns
   true at the "Single statements are always kept in their original order"
   early exit before it reaches the loop-invariant-read guard.  For the pair
   (invariant load *p, ungrouped store b[i]) both refs are ungrouped, so the
   guard is skipped and vect_prune_runtime_alias_test_list drops the runtime
   alias check under the VF == 1 rule.  vectorizable_load then hoists the
   VMAT_INVARIANT load into the preheader with nothing guarding the aliasing.

   The vector(1) __int128 store keeps the SLP unroll factor at 1 while staying
   ungrouped, and the int store group provides an SLP root with more than one
   lane so that vectorisation is still attempted.

   Expected (scalar): c[0] == 5, c[1..7] == 77.
   -O3 gives c[0..7] == 5.  */

typedef __int128 i128;

__attribute__((noipa))
void h (int *a, i128 *b, i128 *c, i128 *p, i128 *q, int n)
{
  for (int i = 0; i < n; i++)
    {
      a[4*i] = 1; a[4*i+1] = 2; a[4*i+2] = 3; a[4*i+3] = 4;
      c[i] = *p;
      b[i] = *q;
    }
}

int a[32];
i128 b[8], c[8];
i128 qv = 77;

int main (void)
{
  for (int i = 0; i < 8; i++) { b[i] = 5 + i; c[i] = -1; }
  h (a, b, c, &b[0], &qv, 8);
  if ((int) c[0] != 5)
    __builtin_abort ();
  for (int i = 1; i < 8; i++)
    if ((int) c[i] != 77)
      __builtin_abort ();
  return 0;
}

Aborts on aarch64 at -O3 and passes at -O1

Reply via email to