https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77278
--- Comment #22 from rguenther at suse dot de <rguenther at suse dot de> --- On Tue, 4 Jun 2019, tkoenig at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77278 > > --- Comment #19 from Thomas Koenig <tkoenig at gcc dot gnu.org> --- > (In reply to rguent...@suse.de from comment #15) > Btw, I wonder what happens at > > the call boundary inside a single fortran module where > > the caller passes a dim[2] array to a subroutine > > handling arbitrary dimension arrays? I suspect the > > IL would have the very same TBAA issue. Can you produce > > a fortran testcase that exposes such a case so we can have a > > look into the details? > > Here is a test case: > > module x > implicit none > contains > subroutine foo(a) > real, dimension(..) :: a > print *,shape(a) > end subroutine foo > subroutine bar > real, dimension(2,2) :: a > real, dimension(3,3,3) :: b > call foo(a) > call foo(b) > end subroutine bar > end module x > > program main > use x > call bar > end program main > > Looking at the *.original tree dump, we have > > bar () > { > real(kind=4) a[4]; > real(kind=4) b[27]; > > { > struct array02_real(kind=4) parm.0; > > [...] > > foo (&parm.0); > } > > { > struct array03_real(kind=4) parm.1; > > [...] > > foo (&parm.1); > } > > and > > foo (struct array15_real(kind=4) & restrict a) > { > { > struct __st_parameter_dt dt_parm.2; > > This does not really look very healthy (but it is not warned about). OK, so changing the testcase to module x implicit none contains subroutine foo(a) real, dimension(..) :: a if (rank(a) < 2) STOP 3 end subroutine foo subroutine bar real, dimension(2,2) :: a real, dimension(3,3,3) :: b call foo(a) call foo(b) end subroutine bar end module x program main use x call bar end program main makes us inline foo() where we then see struct array03_real(kind=4) parm.1; struct array02_real(kind=4) parm.0; ... parm.0.dtype.rank = 2; ... _15 = MEM[(struct array15_real(kind=4) &)&parm.0].dtype.rank; if (_15 <= 1) which shows a possible wrong-code issue because the store to rank is via array02 but the read uses array15. We don't miscompile this because we try to be forgiving if we see a must-alias. The frontend should create a descriptor type mimicing the one in the library API and emit MEM[(struct arrayN_real(kind=4) &)¶m.0].dtype.rank = 2; ... _15 = MEM[(struct arrayN_real(kind=4) &)¶m.0].dtype.rank; if (_15 <= 1) that is, all accesses to array descriptors should be as-if they were indirect accesses through the assumed rank descriptor type with the flex-array dim member. Note this would no longer allow TBAA disambiguation of different rank array descriptor accesses. So alternatively we would have to arrange accesses via structs with a flex array member alias accesses via structs with fixed-array members. Still functions accessing assumed rank arrays like foo() above then need to use the flexarray descriptor type to access dtype.rank, not as it does at the moment the max-rank descriptor type. I suppose that would be the first thing to fix (maybe also the easiest). Honza and me can then think about ways to make struct { int ndim; int dim[]; } accesses conflict with struct { int ndim; int dim[N]; } with arbitrary N. Like in record-component-aliases if it sees a trailing fixed-size array member, build the corresponding flex-array record and record a subset of that (ugh).