https://gcc.gnu.org/g:9919b2a44ec4a3f6042569637ee6fd784d427fa4
commit r13-10335-g9919b2a44ec4a3f6042569637ee6fd784d427fa4 Author: Thomas Koenig <[email protected]> Date: Wed May 20 22:43:10 2026 +0200 PR fortran/106546 - inline matmul with -fno-automatic There was a problem caused with allocatable arrays used for front-end optimization when -fno-automatic was specified. Solved by explicitly setting the automatic attribute on the symbol. It required "-O2 -fcheck=bounds -fno-automatic" to be seen. gcc/fortran/ChangeLog: PR fortran/106546 * frontend-passes.cc (create_var): Set attr->automatic on new symbol. (create_do_loop): Likewise on iteration variable. gcc/testsuite/ChangeLog: PR fortran/106546 * gfortran.dg/inline_matmul_27.f90: New test. (cherry picked from commit 996673496e9cbc05b6ec55f0ab1324c3ffe4a876) Diff: --- gcc/fortran/frontend-passes.cc | 2 + gcc/testsuite/gfortran.dg/inline_matmul_27.f90 | 63 ++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/gcc/fortran/frontend-passes.cc b/gcc/fortran/frontend-passes.cc index efa5567e9fbc..f6fc0794abb7 100644 --- a/gcc/fortran/frontend-passes.cc +++ b/gcc/fortran/frontend-passes.cc @@ -846,6 +846,7 @@ create_var (gfc_expr * e, const char *vname) symbol->attr.referenced = 1; symbol->attr.dimension = e->rank > 0; symbol->attr.fe_temp = 1; + symbol->attr.automatic = 1; gfc_commit_symbol (symbol); result = gfc_get_expr (); @@ -3846,6 +3847,7 @@ create_do_loop (gfc_expr *start, gfc_expr *end, gfc_expr *step, locus *where, symbol->attr.referenced = 1; symbol->attr.dimension = 0; symbol->attr.fe_temp = 1; + symbol->attr.automatic = 1; gfc_commit_symbol (symbol); i = gfc_get_expr (); diff --git a/gcc/testsuite/gfortran.dg/inline_matmul_27.f90 b/gcc/testsuite/gfortran.dg/inline_matmul_27.f90 new file mode 100644 index 000000000000..6a5cd4d788a3 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/inline_matmul_27.f90 @@ -0,0 +1,63 @@ +! { dg-do run } +! { dg-options "-O2 -fcheck=bounds -fno-automatic" } +! PR fortran/106546 - FE temporaries have to be automatic +! Original test case by Solomon Gibbs + +subroutine do_multiply() + implicit none + + integer :: rank + real(8) :: draw + + real(8) :: x1(6), x2(6) + real(8), allocatable :: K(:,:), J(:,:), z(:) + + character(len=300) :: out + ! Randomly select rank of operation 0 ... 6 + call random_number(draw) + if (draw .lt. 1/7.0d0) then + rank = 0 + elseif (draw .lt. 2/7.0d0) then + rank = 1 + elseif (draw .lt. 3/7.0d0) then + rank = 2 + elseif (draw .lt. 4/7.0d0) then + rank = 3 + elseif (draw .lt. 5/7.0d0) then + rank = 4 + elseif (draw .lt. 6/7.0d0) then + rank = 5 + else + rank = 6 + endif + + allocate(K(rank, 6)) + allocate(J(rank, rank)) + allocate(z(rank)) + + call random_number(x1) + call random_number(x2) + call random_number(K) + call random_number(J) + call random_number(z) + + ! multiply allocatables using array temporaries + ! Problem occurs here + z = matmul(J, matmul(K, x2 - x1)) + + ! Output z to prevent optimizer elimination + write (out,*) rank," ",z + + deallocate(z, J, K) + +end subroutine do_multiply + +program bogus + implicit none + + integer :: i + do i=1,100 + call do_multiply() + end do + +end program bogus
