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

            Bug ID: 126588
           Summary: Wrong code due to
                    vect_analyze_possibly_independent_ddr
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ktkachov at gcc dot gnu.org
  Target Milestone: ---

/* Candidate: tree-vect-data-refs.cc:367,
vect_analyze_possibly_independent_ddr.

   The ddr between the store q->f[2*i] and the load p->f[2*i] has different
   DR_BASE_OBJECTs, so DDR_COULD_BE_INDEPENDENT_P is set, and its only
   distance vector is (0).  vect_analyze_possibly_independent_ddr drops
   dist == 0 entries and returns true, so vect_analyze_data_ref_dependence
   returns success without running the dist == 0 handling
   (vect_preserves_scalar_order_p, dr_zero_step_indicator) and without
   recording a runtime alias check.  The store group {q->f[2*i],
   q->f[2*i+1]} is emitted at the position of the last store, so the
   vectorised order becomes LOAD_LANES(p) then STORE_LANES(q) instead of
   the scalar store, load, store.  With p == q the odd elements keep 0.  */

struct S { int f[1024]; };

__attribute__((noipa)) void
g (struct S *p, struct S *q, int n)
{
  for (int i = 0; i < n; i++)
    {
      q->f[2*i]     = 1;         /* store group member 0 */
      int t         = p->f[2*i]; /* load sits between the two stores */
      q->f[2*i + 1] = t;         /* store group member 1 */
    }
}

int main (void)
{
  static struct S a;
  g (&a, &a, 16);                /* p == q at run time */
  for (int i = 0; i < 32; i++)
    if (a.f[i] != 1)
      __builtin_abort ();
  return 0;
}

Aborts at -O3 on aarch64 but passes without vectorisation

Reply via email to