blob: b3fa5636a307704dde42c66780cdc37c092de1c7 [file] [edit]
! Tests that a `do concurrent reduce(min:...)` on a scalar maps the reduction
! variable as `tofrom ByRef` (not `ByCopy`) when targeting a device. This is
! needed so the reduced result is written back from the device to the host.
! RUN: %flang_fc1 -emit-hlfir -fopenmp -fdo-concurrent-to-openmp=device %s -o - \
! RUN: | FileCheck %s
! RUN: bbc -emit-hlfir -fopenmp -fdo-concurrent-to-openmp=device %s -o - \
! RUN: | FileCheck %s
subroutine min_reduce(arr, n, min_val)
implicit none
integer, intent(in) :: n
real, intent(in) :: arr(n)
real :: min_val
integer :: i
do concurrent (i=1:n) reduce(min:min_val)
min_val = min(min_val, arr(i))
end do
end subroutine min_reduce
! CHECK-DAG: omp.declare_reduction @[[RED_SYM:.*\.omp]] : f32 init
! CHECK-LABEL: func.func @_QPmin_reduce
! CHECK: %[[MIN_VAL_DECL:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %{{.*}} {uniq_name = "_QFmin_reduceEmin_val"}
! Verify the reduction variable is mapped tofrom + ByRef (not implicit + ByCopy).
! CHECK: %[[MIN_VAL_MAP:.*]] = omp.map.info var_ptr(%[[MIN_VAL_DECL]]#1
! CHECK-SAME: map_clauses(implicit, tofrom) capture(ByRef)
! CHECK-SAME: -> !fir.ref<f32> {name = "_QFmin_reduceEmin_val"}
! CHECK: omp.target kernel_type(spmd)
! CHECK-SAME: map_entries({{.*}}%[[MIN_VAL_MAP]] -> %[[MIN_VAL_ARG:[[:alnum:]]+]]{{.*}})
! CHECK: %[[MIN_VAL_DEV:.*]]:2 = hlfir.declare %[[MIN_VAL_ARG]] {{.*}} "_QFmin_reduceEmin_val"
! CHECK: omp.teams reduction(@[[RED_SYM]] %[[MIN_VAL_DEV]]#0 -> %[[RED_TEAMS:.*]] : !fir.ref<f32>) {
! CHECK: omp.parallel {
! CHECK: omp.distribute {
! CHECK: omp.wsloop reduction(@[[RED_SYM]] %[[RED_TEAMS]] -> %[[RED_WS:.*]] : !fir.ref<f32>) {
! CHECK: omp.loop_nest
! CHECK: } {omp.composite}
! CHECK: } {omp.composite}
! CHECK: } {omp.composite}
! CHECK: } {omp.combined}