[flang][OpenMP] noalias on dummy args causes miscompilation with OMP synchronization at higher optimizations
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
PR https://github.com/llvm/llvm-project/pull/155949/ changed the force-no-alias default from false to true, causing noalias to be added to all qualifying dummy arguments. This is incorrect for functions containing OpenMP synchronization constructs (critical, single, barrier, etc.).LLVM uses noalias to hoist loads before and sink stores after __kmpc_critical calls, breaking the synchronization.
Test case
```fortran
program repro
use omp_lib
implicit none
integer, parameter :: NT = 4, N = 10
real(kind=8) :: tmp, sum
tmp = 0.d0
call omp_set_dynamic(.false.)
call omp_set_num_threads(NT)
!$omp parallel
!$omp parallel if(.FALSE.)
call sub(tmp)
!$omp end parallel
!$omp end parallel
sum = real(NT * N * (N + 1) / 2, 8)
print *, sum, tmp
if (abs(tmp - sum) > 1d-13) then
print *, 'FAIL'
stop 1
else
print *, 'PASS'
end if
end program
subroutine sub(tmp)
implicit none
real(kind=8) :: tmp
integer :: i
!$omp single
do i = 1, 10
!$omp critical
tmp = tmp + real(i, 8)
!$omp end critical
end do
!$omp end single
end subroutine sub
```
```
flang -fopenmp -O0 repro.f90 -o repro && ./repro
220. 220.
PASS
flang -fopenmp -O1 repro.f90 -o repro && ./repro
220. 220.
PASS
flang -fopenmp -O2 repro.f90 -o repro && ./repro
220. 110.
FAIL
Fortran STOP: code 1
flang -fopenmp -O3 repro.f90 -o repro && ./repro
220. 165.
FAIL
Fortran STOP: code 1
```
At higher optimizations, sub_ gets noalias on its tmp argument. LLVM then hoists the single load above all critical sections and sinks the store below them. The critical sections do not protect, and threads race on the value in registers.
Contributor guide
Assessment
This issue has not been assessed yet.