Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions flang/test/Transforms/DoConcurrent/allocatable.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
! Verifies that proper `omp.map.bounds` ops are emitted when an allocatable is
! implicitly mapped by a `do concurrent` loop.

! RUN: %flang_fc1 -emit-hlfir -fopenmp -fdo-concurrent-to-openmp=device %s -o - \
! RUN: | FileCheck %s
program main
implicit none

integer,parameter :: n = 1000000
real, allocatable, dimension(:) :: y
integer :: i

allocate(y(1:n))

do concurrent(i=1:n)
y(i) = 42
end do

deallocate(y)
end program main

! CHECK: %[[Y_DECL:.*]]:2 = hlfir.declare %{{.*}} {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFEy"}
! CHECK: %[[Y_VAL:.*]] = fir.load %[[Y_DECL]]#0
! CHECK: %[[Y_DIM0:.*]]:3 = fir.box_dims %[[Y_VAL]], %{{c0_.*}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

< NIT > I think this test would be more robust if you captured the names of the output values of ops that defined the constants and then matched them to make sure you are getting the 0th dim out of fir.box_dims or subtracting 1 in an arith.subi op.

%[[C0:.*]] = arith.constant 0 : i32
%[[C1:.*]] = arith.constant 1 : i32

Same thing in map_shape_info.f90 below.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed. However, the difficulty of this is that there are constants spread across the IR. So I would have to match all the preceeding constants which will add noise to the test expectations.

Here, I chose instead to match against the constant names as printed by MLIR which I think is stable enough and should be clear that we are matching a 0 or 1 constant based on the name: c0_... or c1_.... Let me know if you still think this is a bad idea.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aah i see, that's fine then to leave it as is. Trying to match all the (redundant) definitions of the constants and to check that one of them matches this use is overkill. Your current approach is fine by me.

! CHECK: %[[Y_LB:.*]] = arith.constant 0 : index
! CHECK: %[[Y_UB:.*]] = arith.subi %[[Y_DIM0]]#1, %{{c1_.*}} : index
! CHECK: %[[Y_BOUNDS:.*]] = omp.map.bounds lower_bound(%[[Y_LB]] : index) upper_bound(%[[Y_UB]] : index) extent(%[[Y_DIM0]]#1 : index)
! CHECK: %[[MEM_MAP:.*]] = omp.map.info {{.*}} bounds(%[[Y_BOUNDS]])
! CHECK: omp.map.info var_ptr(%[[Y_DECL]]#1 : {{.*}}) {{.*}} members(%[[MEM_MAP]] : {{.*}})
63 changes: 63 additions & 0 deletions flang/test/Transforms/DoConcurrent/host_eval.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
! Tests `host_eval` clause code-gen and loop nest bounds on host vs. device.

! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-targets=amdgcn-amd-amdhsa \
! RUN: -fdo-concurrent-to-openmp=device %s -o - \
! RUN: | FileCheck %s --check-prefix=HOST -vv

! RUN: %flang_fc1 -triple amdgcn-amd-amdhsa -emit-hlfir -fopenmp \
! RUN: -fopenmp-is-target-device -fdo-concurrent-to-openmp=device %s -o - \
! RUN: | FileCheck %s --check-prefix=DEVICE

program do_concurrent_host_eval
implicit none
integer :: i, j

do concurrent (i=1:10, j=1:20)
end do
end program do_concurrent_host_eval

! HOST: omp.target host_eval(
! HOST-SAME: %{{[^[:space:]]+}} -> %[[I_LB:[^,]+]],
! HOST-SAME: %{{[^[:space:]]+}} -> %[[I_UB:[^,]+]],
! HOST-SAME: %{{[^[:space:]]+}} -> %[[I_ST:[^,]+]],
! HOST-SAME: %{{[^[:space:]]+}} -> %[[J_LB:[^,]+]],
! HOST-SAME: %{{[^[:space:]]+}} -> %[[J_UB:[^,]+]],
! HOST-SAME: %{{[^[:space:]]+}} -> %[[J_ST:[^,]+]] : {{.*}}) map_entries

! HOST: omp.loop_nest ({{.*}}, {{.*}}) : index = (%[[I_LB]], %[[J_LB]]) to
! HOST-SAME: (%[[I_UB]], %[[J_UB]]) inclusive step
! HOST-SAME: (%[[I_ST]], %[[J_ST]])

! DEVICE: omp.target map_entries(
! DEVICE-SAME: %{{[^[:space:]]+}} -> %[[I_LB_MAP:[^,]+]],
! DEVICE-SAME: %{{[^[:space:]]+}} -> %[[I_UB_MAP:[^,]+]],
! DEVICE-SAME: %{{[^[:space:]]+}} -> %[[I_ST_MAP:[^,]+]],

! DEVICE-SAME: %{{[^[:space:]]+}} -> %[[J_LB_MAP:[^,]+]],
! DEVICE-SAME: %{{[^[:space:]]+}} -> %[[J_UB_MAP:[^,]+]],
! DEVICE-SAME: %{{[^[:space:]]+}} -> %[[J_ST_MAP:[^,]+]],

! DEVICE-SAME: %{{[^[:space:]]+}} -> %{{[^,]+}},
! DEVICE-SAME: %{{[^[:space:]]+}} -> %{{[^,]+}} : {{.*}})

! DEVICE: %[[I_LB_DECL:.*]]:2 = hlfir.declare %[[I_LB_MAP]]
! DEVICE: %[[I_LB:.*]] = fir.load %[[I_LB_DECL]]#1 : !fir.ref<index>

! DEVICE: %[[I_UB_DECL:.*]]:2 = hlfir.declare %[[I_UB_MAP]]
! DEVICE: %[[I_UB:.*]] = fir.load %[[I_UB_DECL]]#1 : !fir.ref<index>

! DEVICE: %[[I_ST_DECL:.*]]:2 = hlfir.declare %[[I_ST_MAP]]
! DEVICE: %[[I_ST:.*]] = fir.load %[[I_ST_DECL]]#1 : !fir.ref<index>

! DEVICE: %[[J_LB_DECL:.*]]:2 = hlfir.declare %[[J_LB_MAP]]
! DEVICE: %[[J_LB:.*]] = fir.load %[[J_LB_DECL]]#1 : !fir.ref<index>

! DEVICE: %[[J_UB_DECL:.*]]:2 = hlfir.declare %[[J_UB_MAP]]
! DEVICE: %[[J_UB:.*]] = fir.load %[[J_UB_DECL]]#1 : !fir.ref<index>

! DEVICE: %[[J_ST_DECL:.*]]:2 = hlfir.declare %[[J_ST_MAP]]
! DEVICE: %[[J_ST:.*]] = fir.load %[[J_ST_DECL]]#1 : !fir.ref<index>

! DEVICE: omp.loop_nest ({{.*}}, {{.*}}) : index = (%[[I_LB]], %[[J_LB]]) to
! DEVICE-SAME: (%[[I_UB]], %[[J_UB]]) inclusive step
! DEVICE-SAME: (%[[I_ST]], %[[J_ST]])
41 changes: 26 additions & 15 deletions flang/test/Transforms/DoConcurrent/locally_destroyed_temp.f90
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
! for a definition of "loop-local values" and how they are handled.

! RUN: %flang_fc1 -emit-hlfir -fopenmp -fdo-concurrent-to-openmp=host %s -o - \
! RUN: | FileCheck %s
! RUN: | FileCheck %s --check-prefixes=COMMON

! RUN: %flang_fc1 -emit-hlfir -fopenmp -fdo-concurrent-to-openmp=device %s -o - \
! RUN: | FileCheck %s --check-prefixes=COMMON,DEVICE
module struct_mod
type test_struct
integer, allocatable :: x_
Expand Down Expand Up @@ -46,17 +49,25 @@ program main
print *, "total =", total
end program main

! CHECK: omp.parallel {
! CHECK: %[[LOCAL_TEMP:.*]] = fir.alloca !fir.type<_QMstruct_modTtest_struct{x_:!fir.box<!fir.heap<i32>>}> {bindc_name = ".result"}
! CHECK: omp.wsloop {
! CHECK: omp.loop_nest {{.*}} {
! CHECK: %[[TEMP_VAL:.*]] = fir.call @_QMstruct_modPconstruct_from_components
! CHECK: fir.save_result %[[TEMP_VAL]] to %[[LOCAL_TEMP]]
! CHECK: %[[EMBOXED_LOCAL:.*]] = fir.embox %[[LOCAL_TEMP]]
! CHECK: %[[CONVERTED_LOCAL:.*]] = fir.convert %[[EMBOXED_LOCAL]]
! CHECK: fir.call @_FortranADestroy(%[[CONVERTED_LOCAL]])
! CHECK: omp.yield
! CHECK: }
! CHECK: }
! CHECK: omp.terminator
! CHECK: }
! DEVICE: omp.target {{.*}} {
! DEVICE: omp.teams {
! COMMON: omp.parallel {
! COMMON: %[[LOCAL_TEMP:.*]] = fir.alloca !fir.type<_QMstruct_modTtest_struct{x_:!fir.box<!fir.heap<i32>>}> {bindc_name = ".result"}
! DEVICE: omp.distribute {
! COMMON: omp.wsloop {
! COMMON: omp.loop_nest {{.*}} {
! COMMON: %[[TEMP_VAL:.*]] = fir.call @_QMstruct_modPconstruct_from_components
! COMMON: fir.save_result %[[TEMP_VAL]] to %[[LOCAL_TEMP]]
! COMMON: %[[EMBOXED_LOCAL:.*]] = fir.embox %[[LOCAL_TEMP]]
! COMMON: %[[CONVERTED_LOCAL:.*]] = fir.convert %[[EMBOXED_LOCAL]]
! COMMON: fir.call @_FortranADestroy(%[[CONVERTED_LOCAL]])
! COMMON: omp.yield
! COMMON: }
! COMMON: }
! DEVICE: }
! COMMON: omp.terminator
! COMMON: }
! DEVICE: omp.terminator
! DEVICE: }
! DEVICE: omp.terminator
! DEVICE: }
104 changes: 104 additions & 0 deletions flang/test/Transforms/DoConcurrent/map_shape_info.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
! Tests mapping of a basic `do concurrent` loop to
! `!$omp target teams distribute parallel do`.
! RUN: %flang_fc1 -emit-hlfir -fopenmp -fdo-concurrent-to-openmp=device %s -o - \
! RUN: | FileCheck %s

program do_concurrent_shape
implicit none
integer :: a(10, 20)
integer :: i, j

do concurrent (i=1:10, j=1:20)
a(i, j) = i * j
end do
end program do_concurrent_shape

! CHECK: fir.store %{{c10.*}} to %[[DIM0_EXT:.*]] : !fir.ref<index>
! CHECK: fir.store %{{c20.*}} to %[[DIM1_EXT:.*]] : !fir.ref<index>

! CHECK: omp.map.info
! CHECK: omp.map.info
! CHECK: omp.map.info

! CHECK: omp.map.info
! CHECK: omp.map.info
! CHECK: omp.map.info

! CHECK: omp.map.info
! CHECK: omp.map.info
! CHECK: omp.map.info

! CHECK: %[[DIM0_EXT_MAP:.*]] = omp.map.info
! CHECK-SAME: var_ptr(%[[DIM0_EXT]] : !fir.ref<index>, index)
! CHECK-SAME: map_clauses(implicit, exit_release_or_enter_alloc)
! CHECK-SAME: capture(ByCopy) -> !fir.ref<index> {name = "_QFEa.extent.dim0"}

! CHECK: %[[DIM1_EXT_MAP:.*]] = omp.map.info
! CHECK-SAME: var_ptr(%[[DIM1_EXT]] : !fir.ref<index>, index)
! CHECK-SAME: map_clauses(implicit, exit_release_or_enter_alloc)
! CHECK-SAME: capture(ByCopy) -> !fir.ref<index> {name = "_QFEa.extent.dim1"}

! CHECK: omp.target host_eval({{.*}}) map_entries(
! CHECK-SAME: %{{[^[:space:]]+}} -> %{{[^,]+}},
! CHECK-SAME: %{{[^[:space:]]+}} -> %{{[^,]+}},
! CHECK-SAME: %{{[^[:space:]]+}} -> %{{[^,]+}},
! CHECK-SAME: %{{[^[:space:]]+}} -> %{{[^,]+}},
! CHECK-SAME: %{{[^[:space:]]+}} -> %{{[^,]+}},
! CHECK-SAME: %{{[^[:space:]]+}} -> %{{[^,]+}},
! CHECK-SAME: %{{[^[:space:]]+}} -> %{{[^,]+}},
! CHECK-SAME: %{{[^[:space:]]+}} -> %{{[^,]+}},
! CHECK-SAME: %{{[^[:space:]]+}} -> %{{[^,]+}},
! CHECK-SAME: %[[DIM0_EXT_MAP]] -> %[[DIM0_EXT_ARG:[^,]+]],
! CHECK-SAME: %[[DIM1_EXT_MAP]] -> %[[DIM1_EXT_ARG:[^,]+]] : {{.*}})

! CHECK-DAG: %[[DIM0_EXT_DEV:.*]] = fir.load %[[DIM0_EXT_ARG]]
! CHECK-DAG: %[[DIM1_EXT_DEV:.*]] = fir.load %[[DIM1_EXT_ARG]]

! CHECK: %[[SHAPE:.*]] = fir.shape %[[DIM0_EXT_DEV]], %[[DIM1_EXT_DEV]]
! CHECK: %{{.*}}:2 = hlfir.declare %{{.*}}(%[[SHAPE]]) {uniq_name = "_QFEa"}

subroutine do_concurrent_shape_shift
implicit none
integer :: a(2:10)
integer :: i

do concurrent (i=1:10)
a(i) = i
end do
end subroutine do_concurrent_shape_shift

! CHECK: fir.store %{{c2.*}} to %[[DIM0_STRT:.*]] : !fir.ref<index>
! CHECK: fir.store %{{c9.*}} to %[[DIM0_EXT:.*]] : !fir.ref<index>

! CHECK: omp.map.info
! CHECK: omp.map.info
! CHECK: omp.map.info

! CHECK: omp.map.info
! CHECK: omp.map.info

! CHECK: %[[DIM0_STRT_MAP:.*]] = omp.map.info
! CHECK-SAME: var_ptr(%[[DIM0_STRT]] : !fir.ref<index>, index)
! CHECK-SAME: map_clauses(implicit, exit_release_or_enter_alloc)
! CHECK-SAME: capture(ByCopy) -> !fir.ref<index> {name = "_QF{{.*}}Ea.start_idx.dim0"}

! CHECK: %[[DIM0_EXT_MAP:.*]] = omp.map.info
! CHECK-SAME: var_ptr(%[[DIM0_EXT]] : !fir.ref<index>, index)
! CHECK-SAME: map_clauses(implicit, exit_release_or_enter_alloc)
! CHECK-SAME: capture(ByCopy) -> !fir.ref<index> {name = "_QF{{.*}}Ea.extent.dim0"}

! CHECK: omp.target host_eval({{.*}}) map_entries(
! CHECK-SAME: %{{[^[:space:]]+}} -> %{{[^,]+}},
! CHECK-SAME: %{{[^[:space:]]+}} -> %{{[^,]+}},
! CHECK-SAME: %{{[^[:space:]]+}} -> %{{[^,]+}},
! CHECK-SAME: %{{[^[:space:]]+}} -> %{{[^,]+}},
! CHECK-SAME: %{{[^[:space:]]+}} -> %{{[^,]+}},
! CHECK-SAME: %[[DIM0_STRT_MAP]] -> %[[DIM0_STRT_ARG:[^,]+]],
! CHECK-SAME: %[[DIM0_EXT_MAP]] -> %[[DIM0_EXT_ARG:[^,]+]] : {{.*}})

! CHECK-DAG: %[[DIM0_STRT_DEV:.*]] = fir.load %[[DIM0_STRT_ARG]]
! CHECK-DAG: %[[DIM0_EXT_DEV:.*]] = fir.load %[[DIM0_EXT_ARG]]

! CHECK: %[[SHAPE_SHIFT:.*]] = fir.shape_shift %[[DIM0_STRT_DEV]], %[[DIM0_EXT_DEV]]
! CHECK: %{{.*}}:2 = hlfir.declare %{{.*}}(%[[SHAPE_SHIFT]]) {uniq_name = "_QF{{.*}}Ea"}

104 changes: 63 additions & 41 deletions flang/test/Transforms/DoConcurrent/multiple_iteration_ranges.f90
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
! RUN: split-file %s %t

! RUN: %flang_fc1 -emit-hlfir -fopenmp -fdo-concurrent-to-openmp=host %t/multi_range.f90 -o - \
! RUN: | FileCheck %s
! RUN: | FileCheck %s --check-prefixes=HOST,COMMON

! RUN: %flang_fc1 -emit-hlfir -fopenmp -fdo-concurrent-to-openmp=device %t/multi_range.f90 -o - \
! RUN: | FileCheck %s --check-prefixes=DEVICE,COMMON

!--- multi_range.f90
program main
Expand All @@ -17,56 +20,75 @@ program main
end do
end

! CHECK: func.func @_QQmain
! COMMON: func.func @_QQmain

! COMMON: %[[C3:.*]] = arith.constant 3 : i32
! COMMON: %[[LB_I:.*]] = fir.convert %[[C3]] : (i32) -> index
! COMMON: %[[C20:.*]] = arith.constant 20 : i32
! COMMON: %[[UB_I:.*]] = fir.convert %[[C20]] : (i32) -> index
! COMMON: %[[STEP_I:.*]] = arith.constant 1 : index

! COMMON: %[[C5:.*]] = arith.constant 5 : i32
! COMMON: %[[LB_J:.*]] = fir.convert %[[C5]] : (i32) -> index
! COMMON: %[[C40:.*]] = arith.constant 40 : i32
! COMMON: %[[UB_J:.*]] = fir.convert %[[C40]] : (i32) -> index
! COMMON: %[[STEP_J:.*]] = arith.constant 1 : index

! COMMON: %[[C7:.*]] = arith.constant 7 : i32
! COMMON: %[[LB_K:.*]] = fir.convert %[[C7]] : (i32) -> index
! COMMON: %[[C60:.*]] = arith.constant 60 : i32
! COMMON: %[[UB_K:.*]] = fir.convert %[[C60]] : (i32) -> index
! COMMON: %[[STEP_K:.*]] = arith.constant 1 : index

! DEVICE: omp.target host_eval(
! DEVICE-SAME: %[[LB_I]] -> %[[LB_I:[[:alnum:]]+]],
! DEVICE-SAME: %[[UB_I]] -> %[[UB_I:[[:alnum:]]+]],
! DEVICE-SAME: %[[STEP_I]] -> %[[STEP_I:[[:alnum:]]+]],
! DEVICE-SAME: %[[LB_J]] -> %[[LB_J:[[:alnum:]]+]],
! DEVICE-SAME: %[[UB_J]] -> %[[UB_J:[[:alnum:]]+]],
! DEVICE-SAME: %[[STEP_J]] -> %[[STEP_J:[[:alnum:]]+]],
! DEVICE-SAME: %[[LB_K]] -> %[[LB_K:[[:alnum:]]+]],
! DEVICE-SAME: %[[UB_K]] -> %[[UB_K:[[:alnum:]]+]],
! DEVICE-SAME: %[[STEP_K]] -> %[[STEP_K:[[:alnum:]]+]] :
! DEVICE-SAME: index, index, index, index, index, index, index, index, index)

! CHECK: %[[C3:.*]] = arith.constant 3 : i32
! CHECK: %[[LB_I:.*]] = fir.convert %[[C3]] : (i32) -> index
! CHECK: %[[C20:.*]] = arith.constant 20 : i32
! CHECK: %[[UB_I:.*]] = fir.convert %[[C20]] : (i32) -> index
! CHECK: %[[STEP_I:.*]] = arith.constant 1 : index
! DEVICE: omp.teams

! CHECK: %[[C5:.*]] = arith.constant 5 : i32
! CHECK: %[[LB_J:.*]] = fir.convert %[[C5]] : (i32) -> index
! CHECK: %[[C40:.*]] = arith.constant 40 : i32
! CHECK: %[[UB_J:.*]] = fir.convert %[[C40]] : (i32) -> index
! CHECK: %[[STEP_J:.*]] = arith.constant 1 : index
! HOST-NOT: omp.target
! HOST-NOT: omp.teams

! CHECK: %[[C7:.*]] = arith.constant 7 : i32
! CHECK: %[[LB_K:.*]] = fir.convert %[[C7]] : (i32) -> index
! CHECK: %[[C60:.*]] = arith.constant 60 : i32
! CHECK: %[[UB_K:.*]] = fir.convert %[[C60]] : (i32) -> index
! CHECK: %[[STEP_K:.*]] = arith.constant 1 : index
! COMMON: omp.parallel {

! CHECK: omp.parallel {
! COMMON-NEXT: %[[ITER_VAR_I:.*]] = fir.alloca i32 {bindc_name = "i"}
! COMMON-NEXT: %[[BINDING_I:.*]]:2 = hlfir.declare %[[ITER_VAR_I]] {uniq_name = "_QFEi"}

! CHECK-NEXT: %[[ITER_VAR_I:.*]] = fir.alloca i32 {bindc_name = "i"}
! CHECK-NEXT: %[[BINDING_I:.*]]:2 = hlfir.declare %[[ITER_VAR_I]] {uniq_name = "_QFEi"}
! COMMON-NEXT: %[[ITER_VAR_J:.*]] = fir.alloca i32 {bindc_name = "j"}
! COMMON-NEXT: %[[BINDING_J:.*]]:2 = hlfir.declare %[[ITER_VAR_J]] {uniq_name = "_QFEj"}

! CHECK-NEXT: %[[ITER_VAR_J:.*]] = fir.alloca i32 {bindc_name = "j"}
! CHECK-NEXT: %[[BINDING_J:.*]]:2 = hlfir.declare %[[ITER_VAR_J]] {uniq_name = "_QFEj"}
! COMMON-NEXT: %[[ITER_VAR_K:.*]] = fir.alloca i32 {bindc_name = "k"}
! COMMON-NEXT: %[[BINDING_K:.*]]:2 = hlfir.declare %[[ITER_VAR_K]] {uniq_name = "_QFEk"}

! CHECK-NEXT: %[[ITER_VAR_K:.*]] = fir.alloca i32 {bindc_name = "k"}
! CHECK-NEXT: %[[BINDING_K:.*]]:2 = hlfir.declare %[[ITER_VAR_K]] {uniq_name = "_QFEk"}
! DEVICE: omp.distribute

! CHECK: omp.wsloop {
! CHECK-NEXT: omp.loop_nest
! CHECK-SAME: (%[[ARG0:[^[:space:]]+]], %[[ARG1:[^[:space:]]+]], %[[ARG2:[^[:space:]]+]])
! CHECK-SAME: : index = (%[[LB_I]], %[[LB_J]], %[[LB_K]])
! CHECK-SAME: to (%[[UB_I]], %[[UB_J]], %[[UB_K]]) inclusive
! CHECK-SAME: step (%[[STEP_I]], %[[STEP_J]], %[[STEP_K]]) {
! COMMON: omp.wsloop {
! COMMON-NEXT: omp.loop_nest
! COMMON-SAME: (%[[ARG0:[^[:space:]]+]], %[[ARG1:[^[:space:]]+]], %[[ARG2:[^[:space:]]+]])
! COMMON-SAME: : index = (%[[LB_I]], %[[LB_J]], %[[LB_K]])
! COMMON-SAME: to (%[[UB_I]], %[[UB_J]], %[[UB_K]]) inclusive
! COMMON-SAME: step (%[[STEP_I]], %[[STEP_J]], %[[STEP_K]]) {

! CHECK-NEXT: %[[IV_IDX_I:.*]] = fir.convert %[[ARG0]]
! CHECK-NEXT: fir.store %[[IV_IDX_I]] to %[[BINDING_I]]#0
! COMMON-NEXT: %[[IV_IDX_I:.*]] = fir.convert %[[ARG0]]
! COMMON-NEXT: fir.store %[[IV_IDX_I]] to %[[BINDING_I]]#0

! CHECK-NEXT: %[[IV_IDX_J:.*]] = fir.convert %[[ARG1]]
! CHECK-NEXT: fir.store %[[IV_IDX_J]] to %[[BINDING_J]]#0
! COMMON-NEXT: %[[IV_IDX_J:.*]] = fir.convert %[[ARG1]]
! COMMON-NEXT: fir.store %[[IV_IDX_J]] to %[[BINDING_J]]#0

! CHECK-NEXT: %[[IV_IDX_K:.*]] = fir.convert %[[ARG2]]
! CHECK-NEXT: fir.store %[[IV_IDX_K]] to %[[BINDING_K]]#0
! COMMON-NEXT: %[[IV_IDX_K:.*]] = fir.convert %[[ARG2]]
! COMMON-NEXT: fir.store %[[IV_IDX_K]] to %[[BINDING_K]]#0

! CHECK: omp.yield
! CHECK-NEXT: }
! CHECK-NEXT: }
! COMMON: omp.yield
! COMMON-NEXT: }
! COMMON-NEXT: }

! CHECK-NEXT: omp.terminator
! CHECK-NEXT: }
! HOST-NEXT: omp.terminator
! HOST-NEXT: }
Loading