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

--- Comment #37 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to rguent...@suse.de from comment #36)
> On Sun, 27 Mar 2022, mikael at gcc dot gnu.org wrote:
> 
> > For gcc-12, is there a way to add a middle-end workaround using annotations 
> > on
> > descriptor types (a lang flag or something) ?
> 
> I will think of what options we have to work around this in the
> middle-end (maybe with help of the frontend during gimplification).

So the difficult issue is that the intended effect of the ARRAY_REF is to
apply a negative offset to its base.  That's something fundamentally not
supported for any handled component reference, especially when it is a
non-constant negative offset.  An access is currently constrained to
[offset, offset + max_size] where max_size can be unknown (we use a special
value of -1 for that).  In particular 'offset' cannot be unknown, but when
we split the ultimate base object we do support a constant negative offset
from the real base object.  So we consider a get_base_address() base
plus [0, 0 + unknown] to be a valid conservative answer - but for the
fortran ARRAY_REF indexing it would not be!

Now - actual miscompilations of course require more specific setups, the
ones cited here take advantage of knowing the size of the underlying object
and together with the offset >= 0 constraint constraining the variable index
to exactly the last element of the array.  We already have
-funconstrained-commons to catch a similar case (but with trailing arrays
here).

On the middle-end side it's hard to tell whether the actual array
reference is from a "safe" one (not via an array descriptor and not with
negative stride), so truly fixing it there with lowering the ARRAY_REF
to pointer arithmetic would be a mass-rewrite of even safe accesses.

Another effect besides the wrong constant propagation would be
disambiguation of accesses.  Like if we had

  integer, dimension (10) :: a
  do i = 1, 10
    reshape(a, (/10:1:-1/))(i) = a(i)
  end do

(sorry for my likely invalid fortran, but you get the idea), then
the middle-end would disambiguate all a(i) besides a(10) against the
store.

To sum up, I don't see a good way to workaround this in the middle-end
(without a really big hammer that would do more harm than good).  I also
do not see a way to teach the middle-end negative offsetting ARRAY_REFs,
even if you'd call them differently.

The issue itself is long latent so we probably have to live with GCC 12
exposing slightly more cases of it in the real world (I have yet to see
one there).

Reply via email to