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