llvm-project/flang/test/Lower/OpenMP/shared-loop.f90
Slava Zakharin d6e20c42c1
[flang] Clean-up for fir.do_loop generation in lowering. (#160630)
This patch changes two things:
  1. We do not need to use the loop counter's last value
     for regular do-loops in Lowering.
  2. The loop counter's increment is implied by fir.do_loop
     operation, so there is no need to increment it explicitly.

The last point has been especially confusing to me, because it was
unclear why we have an explicit increment if it is implied.
It looks like CFGConversion somehow still makes the final code
correct, i.e. the counter is not incremented twice.
Anyway, the new lowering should look more concise.
2025-09-26 09:40:04 -07:00

121 lines
4.2 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:.*]] = fir.do_loop %[[ARG0:.*]] = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%[[ARG1:.*]] =
! CHECK: fir.store %[[ARG1]] to %[[DECL_I]]#0
! CHECK: hlfir.assign
! CHECK: %[[LOAD_I:.*]] = fir.load %[[DECL_I]]#0
! CHECK: %[[RES_I:.*]] = arith.addi %[[LOAD_I]], %{{.*}}
! CHECK: fir.result %[[RES_I]]
! CHECK: }
! CHECK: fir.store %[[RES]] to %[[DECL_I]]#0
! 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:.*]] = 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]]#0
! CHECK: hlfir.assign
! CHECK: %[[LOAD_I:.*]] = fir.load %[[DECL_PRIV_I]]#0
! CHECK: %[[RES_I:.*]] = arith.addi %[[LOAD_I]], %{{.*}}
! CHECK: fir.result %[[RES_I]]
! CHECK: }
! CHECK: fir.store %[[RES]] to %[[DECL_PRIV_I]]#0
! 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:.*]] = 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]]#0
! CHECK: hlfir.assign
! CHECK: %[[LOAD_I:.*]] = fir.load %[[DECL_PRIV_I]]#0
! CHECK: %[[RES_I:.*]] = arith.addi %[[LOAD_I]], %{{.*}}
! CHECK: fir.result %[[RES_I]]
! CHECK: }
! CHECK: fir.store %[[RES]] to %[[DECL_PRIV_I]]#0
! 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