- Notifications
You must be signed in to change notification settings - Fork 15.3k
Closed
Labels
Description
The test program below was expected to print 1 for all threads, but it is printing 1 only for one of the threads:
program main implicit none integer, save :: i = 0 !$omp threadprivate(i) !$omp parallel call foo !$omp critical print *, i !$omp end critical !$omp end parallel contains subroutine foo() !$omp single i = 1 !$omp end single copyprivate(i) end subroutine end programfoo's FIR is missing an omp.threadprivate operation and is using the original i variable instead:
func.func private @_QFPfoo() attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} { %0 = fir.address_of(@_QFEi) : !fir.ref<i32> %1:2 = hlfir.declare %0 {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) omp.single copyprivate(%1#0 -> @_copy_i32 : !fir.ref<i32>) { %c1_i32 = arith.constant 1 : i32 hlfir.assign %c1_i32 to %1#0 : i32, !fir.ref<i32> omp.terminator } return } By manually adding an omp.threadprivate operation (and using its result instead), the program works as expected:
func.func private @_QFPfoo() attributes {fir.internal_proc, llvm.linkage = #llvm.linkage<internal>} { %0 = fir.address_of(@_QFEi) : !fir.ref<i32> %1:2 = hlfir.declare %0 {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) %2 = omp.threadprivate %1#1 : !fir.ref<i32> -> !fir.ref<i32> %3:2 = hlfir.declare %2 {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) omp.single copyprivate(%3#0 -> @_copy_i32 : !fir.ref<i32>) { %c1_i32 = arith.constant 1 : i32 hlfir.assign %c1_i32 to %3#0 : i32, !fir.ref<i32> omp.terminator } return } The issue doesn't seem related to copyprivate, as other similar programs also show the same behavior:
program main implicit none integer, save :: i = 0 !$omp threadprivate(i) !$omp parallel call foo !$omp critical print *, i !$omp end critical !$omp end parallel contains subroutine foo() i = 1 end subroutine end programThe issue also happens if the i = 1 line is wrapped inside a parallel directive.