Files
clang-p2996/flang/test/Lower/OpenMP/shared-loop.f90
Mats Petersson 8e10a3f80e [flang][OpenMP] don't privatise loop index marked shared (#108176)
Mark the symbol with OmpShared, and then check that later in lowering to
avoid making a local loop index.

OpenMP 5.2 says: "Loop iteration variables of loops that are not associated 
with any OpenMP directive maybe listed in data-sharing attribute clauses on
the surrounding teams, parallel or taskgenerating construct, and on enclosed
constructs, subject to other restrictions."

Tests updated to match the extra OmpShared attribute.

Add regression test for lowering to hlfir.

Closes #102961

---------

Co-authored-by: Tom Eccles <tom.eccles@arm.com>
2024-09-13 12:57:11 +01:00

121 lines
4.4 KiB
Fortran

! RUN: bbc -emit-hlfir -fopenmp %s -o - | FileCheck %s
! RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
! --- Check that with shared(i) the variable outside the parallel section
! --- is updated.
! CHECK-LABEL: func.func @_QPomploop()
! CHECK: %[[ALLOC_I:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFomploopEi"}
! CHECK: %[[DECL_I:.*]]:2 = hlfir.declare %[[ALLOC_I]] {uniq_name = "_QFomploopEi"} :
! CHECK: omp.parallel {
! CHECK: omp.sections {
! CHECK: omp.section {
! CHECK: %[[RES:.*]]:2 = fir.do_loop %[[ARG0:.*]] = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%[[ARG1:.*]] =
! CHECK: fir.store %[[ARG1]] to %[[DECL_I]]#1
! CHECK: %[[UPDATE_ITER:.*]] = arith.addi %[[ARG0]], %{{.*}}
! CHECK: %[[LOAD_I:.*]] = fir.load %[[DECL_I]]#1
! CHECK: %[[RES_I:.*]] = arith.addi %[[LOAD_I]], %{{.*}}
! CHECK: fir.result %[[UPDATE_ITER]], %[[RES_I]]
! CHECK: }
! CHECK: fir.store %[[RES]]#1 to %[[DECL_I]]#1
! CHECK: omp.terminator
! CHECK: }
! CHECK: omp.terminator
! CHECK: }
! CHECK: return
! CHECK: }
subroutine omploop
implicit none
integer :: i, j
i = 1
j = 0
!$omp parallel shared(i)
!$omp sections
do i=1,10
j = j + i
end do
!$omp end sections
!$omp end parallel
end subroutine
! --- Check that with default(shared) the variable outside the parallel section
! --- is NOT updated (i is private to the omp.parallel code)
! CHECK-LABEL: func.func @_QPomploop2()
! CHECK: %[[ALLOC_I:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFomploop2Ei"}
! CHECK: %[[DECL_I:.*]]:2 = hlfir.declare %[[ALLOC_I]] {uniq_name = "_QFomploop2Ei"} :
! CHECK: omp.parallel {
! CHECK: %[[ALLOC_PRIV_I:.*]] = fir.alloca i32 {bindc_name = "i", pinned}
! CHECK: %[[DECL_PRIV_I:.*]]:2 = hlfir.declare %[[ALLOC_PRIV_I]]
! CHECK: omp.sections {
! CHECK: omp.section {
! CHECK: %[[RES:.*]]:2 = fir.do_loop %[[ARG0:.*]] = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%[[ARG1:.*]] =
! CHECK-NOT: fir.store %[[ARG1]] to %[[DECL_I]]#1
! CHECK: fir.store %[[ARG1]] to %[[DECL_PRIV_I]]#1
! CHECK: %[[UPDATE_ITER:.*]] = arith.addi %[[ARG0]], %{{.*}}
! CHECK: %[[LOAD_I:.*]] = fir.load %[[DECL_PRIV_I]]#1
! CHECK: %[[RES_I:.*]] = arith.addi %[[LOAD_I]], %{{.*}}
! CHECK: fir.result %[[UPDATE_ITER]], %[[RES_I]]
! CHECK: }
! CHECK: fir.store %[[RES]]#1 to %[[DECL_PRIV_I]]#1
! CHECK: omp.terminator
! CHECK: }
! CHECK: omp.terminator
! CHECK: }
! CHECK: return
! CHECK: }
subroutine omploop2
implicit none
integer :: i, j
i = 1
j = 0
!$omp parallel default(shared)
!$omp sections
do i=1,10
j = j + i
end do
!$omp end sections
!$omp end parallel
end subroutine
! --- Check that with no data-sharing the variable outside the parallel section
! --- is NOT updated (i is private to the omp.parallel code)
! CHECK-LABEL: func.func @_QPomploop3()
! CHECK: %[[ALLOC_I:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFomploop3Ei"}
! CHECK: %[[DECL_I:.*]]:2 = hlfir.declare %[[ALLOC_I]] {uniq_name = "_QFomploop3Ei"} :
! CHECK: omp.parallel {
! CHECK: %[[ALLOC_PRIV_I:.*]] = fir.alloca i32 {bindc_name = "i", pinned}
! CHECK: %[[DECL_PRIV_I:.*]]:2 = hlfir.declare %[[ALLOC_PRIV_I]]
! CHECK: omp.sections {
! CHECK: omp.section {
! CHECK: %[[RES:.*]]:2 = fir.do_loop %[[ARG0:.*]] = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%[[ARG1:.*]] =
! CHECK-NOT: fir.store %[[ARG1]] to %[[DECL_I]]#1
! CHECK: fir.store %[[ARG1]] to %[[DECL_PRIV_I]]#1
! CHECK: %[[UPDATE_ITER:.*]] = arith.addi %[[ARG0]], %{{.*}}
! CHECK: %[[LOAD_I:.*]] = fir.load %[[DECL_PRIV_I]]#1
! CHECK: %[[RES_I:.*]] = arith.addi %[[LOAD_I]], %{{.*}}
! CHECK: fir.result %[[UPDATE_ITER]], %[[RES_I]]
! CHECK: }
! CHECK: fir.store %[[RES]]#1 to %[[DECL_PRIV_I]]#1
! CHECK: omp.terminator
! CHECK: }
! CHECK: omp.terminator
! CHECK: }
! CHECK: return
! CHECK: }
subroutine omploop3
implicit none
integer :: i, j
i = 1
j = 0
!$omp parallel
!$omp sections
do i=1,10
j = j + i
end do
!$omp end sections
!$omp end parallel
end subroutine