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

Reply via email to