Created attachment 52950 [details] integer(1) test program Hi gcc/gfortran team, I have two routines that encode and decode two integer(1) IDs (in [1:6] and [1:32] respectively) to a unique 8-byte integer(1), for 192 possible cases. The example that fails should behave like encode(1, 32) returns 77 decode(77) returns [1, 32] but returns either [-5, 33] or sometimes [3,71] With -O3, there are both versions and architectures of gfortran that either work or not. On godbolt (https://godbolt.org/z/5GboahWs1), this is what I see: gfortran | -O3 -mtune=generic | -O3 -march=core-avx2 | 12.1 | OK | OK | 11.3 | OK | OK | 11.2 | OK | OK | 11.1 | OK | OK | 10.3 | OK | ERROR | 10.2 | OK | ERROR | 10.1 | OK | ERROR | 9.4 | OK | ERROR | 9.3 | OK | ERROR | 9.2 | OK | ERROR | 9.1 | OK | ERROR | 8.5 | ERROR | ERROR | 8.4 | ERROR | ERROR | 8.3 | ERROR | ERROR | 8.2 | ERROR | ERROR | 8.1 | ERROR | ERROR | 7.3 | OK | OK | 7.2 | OK | OK | 7.1 | OK | OK | 6.3 | OK | OK | 5.5 | OK | OK | Also note that: - problem is with int8 only; all is OK with int16,int32,int64 - no problems with -O2. I'm attaching the code here as well, thank you, Federico
Can I ask you to see whether -O3 -fno-tree-vectorize avoids the issue and whether -O3 -fno-vect-cost-model makes the issue appear in more versions? It could be that this is a resolved issue that awaits backporting of a fix (or where backporting is too difficult). I can confirm the -O3 -march=core-avx2 failure with GCC 10 and success with GCC 11.
Ok so we have: gfortran | [...] -fno-tree-vectorize | [...] -fno-vect-cost-model 10.3 | OK | ERROR 9.3 | OK | ERROR 8.3 | OK | ERROR
-fno-vect-cost model also does not change behavior on gcc 11/7/6/5 (all OK)
Fixed on master with r11-3718-g91ae6930ed4a87d7.
(In reply to Martin Liška from comment #4) > Fixed on master with r11-3718-g91ae6930ed4a87d7. If anything that just made the issue latent I suspect.
Would be interesting to find what patch broke this and what patch fixed the -mtune=generic case.
We don't know the failure mode and the identified fix isn't likely the fix. Leaving open as non-regression.
(In reply to Andrew Pinski from comment #6) > Would be interesting to find what patch broke this and what patch fixed the > -mtune=generic case. It is not easy bisecting with old compilers - compilation issues keep coming up on more modern systems, and sometimes newer compilers do not compile older compilers...
I can bisect it if someone gives me a case which aborts with the wrong value.
Hi Sam, Thanks for looking into it - here is a simplified version of the test program: you can also test it live at the Compiler Explorer, at this link: https://godbolt.org/z/r63G348hM Thanks, Federico module subs use iso_fortran_env, only: ip => int8 implicit none contains ! from two indices in [1:6] and [1:32], create a unique int8 code elemental integer(ip) function ENCODE(i,j) integer(ip), intent(in) :: i ! loops in [1:6] range integer(ip), intent(in) :: j ! loops in [1:32] range integer(ip) :: k ENCODE = -122_ip + i do k=1_ip,j+1_ip ENCODE = ENCODE+6_ip end do end function ENCODE elemental subroutine DECODE(code,i,j) integer(ip), intent(in) :: code integer(ip), intent(out) :: i,j select case (code) case (-121_ip:82_ip) i = code j = -1_ip ! Child ID loop do while (i>-116_ip) j = j+1_ip i = i-6_ip end do i = i+122_ip case default i = -huge(i) j = -huge(j) end select end subroutine DECODE end module subs program test_int1 use iso_fortran_env, only: ip => int8 use subs implicit none integer(ip) :: i,j,code,id,jd logical :: success integer :: errors errors = 0 do j=1_ip,32_ip do i=1_ip,6_ip code = ENCODE(i,j) call DECODE(code,id,jd) if (i/=id .or. j/=jd) then errors = errors+1 print *, 'i=',i,' j=',j,' code=',code, & merge('error',' ',i/=id.or.j/=jd) endif end do end do success = errors==0 print *, merge('SUCCESS!','ERROR ',errors==0) if (errors>0) print "(*(i0,a))", errors,'/',6_ip*32_ip,' decoding errors ' end program test_int1