Hello world,

the below patch solves a PR (a regression if you just count -O)
by setting the AUTOMATIC flag on all variables generated
by the front end.

OK for trunk and backport?

Best regards

        Thomas

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.
diff --git a/gcc/fortran/frontend-passes.cc b/gcc/fortran/frontend-passes.cc
index 1ea84198d62..243e9315c94 100644
--- a/gcc/fortran/frontend-passes.cc
+++ b/gcc/fortran/frontend-passes.cc
@@ -849,6 +849,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 ();
@@ -3808,6 +3809,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 00000000000..6a5cd4d788a
--- /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

Reply via email to