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

--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> ---
The input to the vectorizer is already bogus:

  _12 = i.0_5 + 536870911;
  _13 = global_data.b[_12];

the issue seems to be that 'sizetype' is used to index the array:

  *(double * const) &global_data.a[(sizetype) i] = *(double * const)
&global_data.a[(sizetype) i] + *(double * const) &global_data.c[(sizetype) i] *
*(double * const) &global_data.d[(sizetype) i];


Ok, so it's one of the suspicious transforms in fold-const.c (I removed all
these sorts of transforms from GIMPLE already...).  try_move_mult_to_index.

Bah.

It's never correct (for later data-dependence) to "reconstruct" ARRAY_REFs
from pointer arithmetic.  Here we fold (ssizetype) (((sizetype) i + 536870911)
* 8) to &global_data.b[(sizetype) i + 536870911].  But that's not the same
as data-dependence analysis doesn't interpret the array index as only
ending up in the address computation which multiplies the index by 8 again
and thus correctly arrives at i * 8 + -8U.  That is, you can't simply
strip an unsigned multiplication this way.

For 64bit we seem to be lucky and we retain

  (sizetype) ((long unsigned int) i * 8) + 18446744073709551608

so we didn't move the multiplication out.  That is because
fold_plusminus_mult_expr only handles signed HWI and 18446744073709551608
is too large for a signed HWI.

So maybe we can apply a not so invasive fix here by restricting both
to signed or unsigned with no sign bit set values.

Doing that fixes the testcase but also ends up with mixed pointer/array
accesses which dependence analysis cannot handle so we get versioning
for aliasing.  If OTOH we disable the offending transform to an array
access we get only pointer-based accesses and data dependence analysis
fails correctly and we don't get anything vectorized here.

Reply via email to