https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84085
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |RESOLVED
Resolution|--- |FIXED
--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
This was indeed fixed in GCC 8. Note that the fundamental issue is that
*(&s1->a1[0][0] + n)
performs an access via 'int *' while s1->a1[N-1][N-1] performs an access
via struct S1 *. This allows the test1 case to disambiguate the load
via s1 against that via s2 by using type-based aliasing. This is not
possible for test2 or test3. We now optimize this solely by the fact
that
*((&s2->a2[0][0] + n)) = *(&s1->a1[0][0] + n);
stores the same value it later loads into *((&s2->a2[0][0] + n)). If you
change this by doing say
*((&s2->a2[0][0] + n)) = *(&s1->a1[0][0] + n) + 1;
it will no longer be optimized.
This may be too conservative reading of the C standard by GCC but we also
have to adhere other languages and tricks done by programmers like viewing
a data array via different multidimensional array shapes by means of
casting.
So, this particular case is fixed in GCC 8.