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