https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126591
Bug ID: 126591
Summary: Wrong code with vect_recog_divmod_pattern and
IFN_DIV_POW2
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Keywords: aarch64-sve, wrong-code
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: ktkachov at gcc dot gnu.org
Target Milestone: ---
! Candidate tree-vect-patterns.cc:5300, vect_recog_divmod_pattern.
! Fortran MODULO on integers is FLOOR_MOD_EXPR. For a power-of-two divisor
! the IFN_DIV_POW2 branch feeds the scaled quotient (q << 3) to
! add_code_for_floorceilround_divmod instead of the remainder, so the
! vectorised MODULO is wrong.
!
! Required flags (aborts):
! gfortran -O3 -march=armv8.2-a+sve
! Same -O and same -march, no abort:
! gfortran -O3 -march=armv8.2-a+sve -fno-tree-vectorize
-fno-tree-slp-vectorize
!
! 62 of 64 lanes are wrong, e.g. MODULO (-32, 8) gives -24 instead of 0.
module m
contains
subroutine fmod8 (a, n)
implicit none
integer, intent(inout) :: a(n)
integer, intent(in) :: n
integer :: i
do i = 1, n
a(i) = modulo (a(i), 8)
end do
end subroutine fmod8
end module m
program main
use m
implicit none
integer, volatile :: nv
integer :: n, i, x, bad
integer, allocatable :: a(:), b(:)
nv = 64
n = nv
allocate (a(n), b(n))
do i = 1, n
x = i - 33
a(i) = x
b(i) = iand (x, 7) ! modulo(x,8) == iand(x,7) in two's complement
end do
call fmod8 (a, n)
bad = 0
do i = 1, n
if (a(i) /= b(i)) then
if (bad < 4) print *, 'in=', i - 33, ' got=', a(i), ' expected=', b(i)
bad = bad + 1
end if
end do
print *, 'bad=', bad
deallocate (a, b)
if (bad /= 0) call abort
end program main
Aborts on aarch64 at -O3 -march=armv8.2-a+sve and passes at -O1