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

            Bug ID: 128071
           Summary: Missed optimization: non-allocatable class array dummy
                    blocks vectorization
           Product: gcc
           Version: 16.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: henri at henrimenke dot de
  Target Milestone: ---

If a non-allocatable class array dummy is used in a loop, gfortran does not
vectorize it, because the data pointer loses restrict.  gfc_build_class_symbol
(class.cc) marks _data as a pointer for dummies that are not allocatable
(attr->dummy && !attr->allocatable), and gfc_get_derived_type (trans-types.cc)
then applies gfc_nonrestricted_type.  In the example below the SLP vectorizer
cannot prove that a and b do not overlap, although they are non-pointer,
non-target dummies, so the 8 additions stay scalar.  With class(t), allocatable
or type(t) dummies the same loop is vectorized.  This causes significant
slowdowns in real-world codes that pass polymorphic arrays to compute kernels.



module m
  type t
    real(8) :: v(8)
  end type
contains
  subroutine f(a, b)
    class(t), intent(inout) :: a(:)
    class(t), intent(in) :: b(:)
    integer :: i
    do i = 1, size(a)
      a(i)%v = a(i)%v + b(i)%v
    end do
  end subroutine
end module



$ gfortran --version
GNU Fortran (GCC) 16.2.0

$ gfortran -O3 -march=x86-64-v4 -c -fdump-tree-slp1-details test.f90
$ objdump -d --disassemble=__m_MOD_f test.o | grep -c vaddsd
8
$ objdump -d --disassemble=__m_MOD_f test.o | grep -c vaddpd
0
$ grep \"can't determine dependence\" test.f90.*.slp1 | head -1
test.f90:11:30: missed:   can't determine dependence between
MEM[(real(kind=8)[8] *)_37][0] and MEM[(real(kind=8)[8] *)_38][1]



Declaring both dummies as class(t), allocatable (test_alloc.f90) or type(t)
(test_type.f90), the loop is vectorized:



$ gfortran -O3 -march=x86-64-v4 -c test_alloc.f90
$ objdump -d --disassemble=__m_MOD_f test_alloc.o | grep -c vaddpd
1
$ gfortran -O3 -march=x86-64-v4 -c test_type.f90
$ objdump -d --disassemble=__m_MOD_f test_type.o | grep -c vaddpd
2

Reply via email to