[Instrumentation] Fix a warning
[llvm-project.git] / flang / test / Fir / convert-to-llvm-openmp-and-fir.fir
blob6e4ac824fbd9cf824ac23257622473338b69acfa
1 // RUN: fir-opt --split-input-file --cfg-conversion --fir-to-llvm-ir="target=aarch64-unknown-linux-gnu" %s | FileCheck %s
3 func.func @_QPsb1(%arg0: !fir.ref<i32> {fir.bindc_name = "n"}, %arg1: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "arr"}) {
4   %c1_i64 = arith.constant 1 : i64
5   %c1_i32 = arith.constant 1 : i32
6   %0 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsbEi"}
7   omp.parallel  {
8     %1 = fir.alloca i32 {adapt.valuebyref, pinned}
9     %2 = fir.load %arg0 : !fir.ref<i32>
10     omp.wsloop nowait {
11       omp.loop_nest (%arg2) : i32 = (%c1_i32) to (%2) inclusive step (%c1_i32)  {
12         fir.store %arg2 to %1 : !fir.ref<i32>
13         %3 = fir.load %1 : !fir.ref<i32>
14         %4 = fir.convert %3 : (i32) -> i64
15         %5 = arith.subi %4, %c1_i64 : i64
16         %6 = fir.coordinate_of %arg1, %5 : (!fir.ref<!fir.array<?xi32>>, i64) -> !fir.ref<i32>
17         fir.store %3 to %6 : !fir.ref<i32>
18         omp.yield
19       }
20     }
21     omp.terminator
22   }
23   return
26 // CHECK-LABEL:  _QPsb1
27 // CHECK-SAME: %[[N_REF:.*]]: !llvm.ptr {fir.bindc_name = "n"}, %[[ARR_REF:.*]]: !llvm.ptr {fir.bindc_name = "arr"}) {
28 // CHECK:    %[[ONE_0:.*]] = llvm.mlir.constant(1 : i64) : i64
29 // CHECK:    %[[ONE_1:.*]] = llvm.mlir.constant(1 : i64) : i64
30 // CHECK:    %[[ONE_2:.*]] = llvm.mlir.constant(1 : i32) : i32
31 // CHECK: omp.parallel   {
32 // CHECK:      %[[ONE_3:.*]] = llvm.mlir.constant(1 : i64) : i64
33 // CHECK:      %[[I_VAR:.*]] = llvm.alloca %[[ONE_3]] x i32 {pinned} : (i64) -> !llvm.ptr
34 // CHECK:      %[[N:.*]] = llvm.load %[[N_REF]] : !llvm.ptr -> i32
35 // CHECK: omp.wsloop nowait
36 // CHECK-NEXT: omp.loop_nest (%[[I:.*]]) : i32 = (%[[ONE_2]]) to (%[[N]]) inclusive step (%[[ONE_2]]) {
37 // CHECK:   llvm.store %[[I]], %[[I_VAR]] : i32, !llvm.ptr
38 // CHECK:   %[[I1:.*]] = llvm.load %[[I_VAR]] : !llvm.ptr -> i32
39 // CHECK:   %[[I1_EXT:.*]] = llvm.sext %[[I1]] : i32 to i64
40 // CHECK:   %[[I_CSTYLE:.*]] = llvm.sub %[[I1_EXT]], %[[ONE_1]]  : i64
41 // CHECK:   %[[ARR_I_REF:.*]] = llvm.getelementptr %[[ARR_REF]][%[[I_CSTYLE]]] : (!llvm.ptr, i64) -> !llvm.ptr
42 // CHECK:   llvm.store %[[I1]], %[[ARR_I_REF]] : i32, !llvm.ptr
43 // CHECK: omp.yield
44 // CHECK: }
45 // CHECK: }
46 // CHECK: omp.terminator
47 // CHECK: }
48 // CHECK: llvm.return
49 // CHECK: }
51 // -----
53 func.func @_QPsb2(%arg0: !fir.ref<i32> {fir.bindc_name = "x"}, %arg1: !fir.ref<i32> {fir.bindc_name = "n"}) {
54   omp.parallel  {
55     omp.master  {
56       %0 = fir.load %arg1 : !fir.ref<i32>
57       fir.store %0 to %arg0 : !fir.ref<i32>
58       omp.terminator
59     }
60     omp.terminator
61   }
62   return
65 // CHECK-LABEL: _QPsb2
66 // CHECK-SAME: %[[X_REF:.*]]: !llvm.ptr {fir.bindc_name = "x"}, %[[N_REF:.*]]: !llvm.ptr {fir.bindc_name = "n"}) {
67 // CHECK: omp.parallel   {
68 // CHECK:   omp.master {
69 // CHECK:     %[[N:.*]] = llvm.load %[[N_REF]] : !llvm.ptr -> i32
70 // CHECK:     llvm.store %[[N]], %[[X_REF]] : i32, !llvm.ptr
71 // CHECK:     omp.terminator
72 // CHECK:   }
73 // CHECK:   omp.terminator
74 // CHECK: }
75 // CHECK: llvm.return
76 // CHECK: }
78 // -----
80 func.func @_QPsb(%arr: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "arr"}) {
81   %0 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsbEi"}
82   omp.parallel   {
83     %c1 = arith.constant 1 : i32
84     %c50 = arith.constant 50 : i32
85     omp.wsloop {
86       omp.loop_nest (%indx) : i32 = (%c1) to (%c50) inclusive step (%c1) {
87         %1 = fir.convert %indx : (i32) -> i64
88         %c1_i64 = arith.constant 1 : i64
89         %2 = arith.subi %1, %c1_i64 : i64
90         %3 = fir.coordinate_of %arr, %2 : (!fir.box<!fir.array<?xi32>>, i64) -> !fir.ref<i32>
91         fir.store %indx to %3 : !fir.ref<i32>
92         omp.yield
93       }
94     }
95     omp.terminator
96   }
97   return
100 // Check only for the structure of the OpenMP portion and the feasibility of the conversion
101 // CHECK-LABEL: @_QPsb
102 // CHECK-SAME: %{{.*}}: !llvm.ptr {fir.bindc_name = "arr"}
103 // CHECK:    omp.parallel   {
104 // CHECK:      %[[C1:.*]] = llvm.mlir.constant(1 : i32) : i32
105 // CHECK:      %[[C50:.*]] = llvm.mlir.constant(50 : i32) : i32
106 // CHECK:      omp.wsloop {
107 // CHECK-NEXT:   omp.loop_nest (%[[INDX:.*]]) : i32 = (%[[C1]]) to (%[[C50]]) inclusive step (%[[C1]]) {
108 // CHECK:          llvm.store %[[INDX]], %{{.*}} : i32, !llvm.ptr
109 // CHECK:          omp.yield
110 // CHECK:      omp.terminator
111 // CHECK:    llvm.return
113 // -----
115 func.func private @foo()
116 func.func private @bar()
118 func.func @sections_no_data() {
119   omp.sections {
120     omp.section {
121       fir.call @foo() : () -> ()
122       omp.terminator
123     }
124     omp.section {
125       fir.call @bar() : () -> ()
126       omp.terminator
127     }
128     omp.terminator
129   }
130   return
133 // CHECK-LABEL: llvm.func @sections_no_data
134 // CHECK: omp.sections {
135 // CHECK:   omp.section {
136 // CHECK:     llvm.call @foo() : () -> ()
137 // CHECK:     omp.terminator
138 // CHECK:   }
139 // CHECK:   omp.section {
140 // CHECK:     llvm.call @bar() : () -> ()
141 // CHECK:     omp.terminator
142 // CHECK:   }
143 // CHECK:   omp.terminator
144 // CHECK: }
146 // -----
148 func.func private @foo(!fir.ref<i32>)
149 func.func private @bar(!fir.ref<i32>, !fir.ref<i32>)
151 func.func @sections_data_without_clauses(%arg0: !fir.ref<i32> {fir.bindc_name = "a"}, %arg1: !fir.ref<i32> {fir.bindc_name = "b"}) {
152   omp.sections {
153     omp.section {
154       fir.call @foo(%arg0) : (!fir.ref<i32>) -> ()
155       omp.terminator
156     }
157     omp.section {
158       fir.call @bar(%arg0, %arg1) : (!fir.ref<i32>, !fir.ref<i32>) -> ()
159       omp.terminator
160     }
161     omp.terminator
162   }
163   return
166 // CHECK-LABEL: llvm.func @sections_data_without_clauses
167 // CHECK-SAME:            (%[[ARG0:.+]]: !llvm.ptr {fir.bindc_name = "a"}, %[[ARG1:.+]]: !llvm.ptr {fir.bindc_name = "b"})
168 // CHECK: omp.sections {
169 // CHECK:   omp.section {
170 // CHECK:     llvm.call @foo(%arg0) : (!llvm.ptr) -> ()
171 // CHECK:     omp.terminator
172 // CHECK:   }
173 // CHECK:   omp.section {
174 // CHECK:     llvm.call @bar(%[[ARG0]], %[[ARG1]]) : (!llvm.ptr, !llvm.ptr) -> ()
175 // CHECK:     omp.terminator
176 // CHECK:   }
177 // CHECK:   omp.terminator
178 // CHECK: }
180 // -----
182 func.func @_QPsimd1(%arg0: !fir.ref<i32> {fir.bindc_name = "n"}, %arg1: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "arr"}) {
183   %c1_i64 = arith.constant 1 : i64
184   %c1_i32 = arith.constant 1 : i32
185   %0 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsbEi"}
186   omp.parallel  {
187     %1 = fir.alloca i32 {adapt.valuebyref, pinned}
188     %2 = fir.load %arg0 : !fir.ref<i32>
189     omp.simd {
190       omp.loop_nest (%arg2) : i32 = (%c1_i32) to (%2) step (%c1_i32) {
191         fir.store %arg2 to %1 : !fir.ref<i32>
192         %3 = fir.load %1 : !fir.ref<i32>
193         %4 = fir.convert %3 : (i32) -> i64
194         %5 = arith.subi %4, %c1_i64 : i64
195         %6 = fir.coordinate_of %arg1, %5 : (!fir.ref<!fir.array<?xi32>>, i64) -> !fir.ref<i32>
196         fir.store %3 to %6 : !fir.ref<i32>
197         omp.yield
198       }
199     }
200     omp.terminator
201   }
202   return
205 // CHECK-LABEL:  _QPsimd1
206 // CHECK-SAME: %[[N_REF:.*]]: !llvm.ptr {fir.bindc_name = "n"}, %[[ARR_REF:.*]]: !llvm.ptr {fir.bindc_name = "arr"}) {
207 // CHECK:    %[[ONE_0:.*]] = llvm.mlir.constant(1 : i64) : i64
208 // CHECK:    %[[ONE_1:.*]] = llvm.mlir.constant(1 : i64) : i64
209 // CHECK:    %[[ONE_2:.*]] = llvm.mlir.constant(1 : i32) : i32
210 // CHECK: omp.parallel   {
211 // CHECK:      %[[ONE_3:.*]] = llvm.mlir.constant(1 : i64) : i64
212 // CHECK:      %[[I_VAR:.*]] = llvm.alloca %[[ONE_3]] x i32 {pinned} : (i64) -> !llvm.ptr
213 // CHECK:      %[[N:.*]] = llvm.load %[[N_REF]] : !llvm.ptr -> i32
214 // CHECK: omp.simd {
215 // CHECK-NEXT: omp.loop_nest (%[[I:.*]]) : i32 = (%[[ONE_2]]) to (%[[N]]) step (%[[ONE_2]]) {
216 // CHECK:   llvm.store %[[I]], %[[I_VAR]] : i32, !llvm.ptr
217 // CHECK:   %[[I1:.*]] = llvm.load %[[I_VAR]] : !llvm.ptr -> i32
218 // CHECK:   %[[I1_EXT:.*]] = llvm.sext %[[I1]] : i32 to i64
219 // CHECK:   %[[I_CSTYLE:.*]] = llvm.sub %[[I1_EXT]], %[[ONE_1]]  : i64
220 // CHECK:   %[[ARR_I_REF:.*]] = llvm.getelementptr %[[ARR_REF]][%[[I_CSTYLE]]] : (!llvm.ptr, i64) -> !llvm.ptr
221 // CHECK:   llvm.store %[[I1]], %[[ARR_I_REF]] : i32, !llvm.ptr
222 // CHECK: omp.yield
223 // CHECK: }
224 // CHECK: }
225 // CHECK: omp.terminator
226 // CHECK: }
227 // CHECK: llvm.return
228 // CHECK: }
230 // -----
232 func.func @_QPomp_target_data() {
233   %c1024 = arith.constant 1024 : index
234   %0 = fir.alloca !fir.array<1024xi32> {bindc_name = "a", uniq_name = "_QFomp_target_dataEa"}
235   %c1024_0 = arith.constant 1024 : index
236   %1 = fir.alloca !fir.array<1024xi32> {bindc_name = "b", uniq_name = "_QFomp_target_dataEb"}
237   %c1024_1 = arith.constant 1024 : index
238   %2 = fir.alloca !fir.array<1024xi32> {bindc_name = "c", uniq_name = "_QFomp_target_dataEc"}
239   %c1024_2 = arith.constant 1024 : index
240   %3 = fir.alloca !fir.array<1024xi32> {bindc_name = "d", uniq_name = "_QFomp_target_dataEd"}
241   %c1 = arith.constant 1 : index
242   %c0 = arith.constant 0 : index
243   %4 = arith.subi %c1024, %c1 : index
244   %5 = omp.map.bounds   lower_bound(%c0 : index) upper_bound(%4 : index) extent(%c1024 : index) stride(%c1 : index) start_idx(%c1 : index)
245   %6 = omp.map.info var_ptr(%0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>)   map_clauses(to) capture(ByRef) bounds(%5) -> !fir.ref<!fir.array<1024xi32>> {name = "a"}
246   %c1_3 = arith.constant 1 : index
247   %c0_4 = arith.constant 0 : index
248   %7 = arith.subi %c1024_0, %c1_3 : index
249   %8 = omp.map.bounds   lower_bound(%c0_4 : index) upper_bound(%7 : index) extent(%c1024_0 : index) stride(%c1_3 : index) start_idx(%c1_3 : index)
250   %9 = omp.map.info var_ptr(%1 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>)   map_clauses(to) capture(ByRef) bounds(%8) -> !fir.ref<!fir.array<1024xi32>> {name = "b"}
251   %c1_5 = arith.constant 1 : index
252   %c0_6 = arith.constant 0 : index
253   %10 = arith.subi %c1024_1, %c1_5 : index
254   %11 = omp.map.bounds   lower_bound(%c0_6 : index) upper_bound(%10 : index) extent(%c1024_1 : index) stride(%c1_5 : index) start_idx(%c1_5 : index)
255   %12 = omp.map.info var_ptr(%2 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>)   map_clauses(always, exit_release_or_enter_alloc) capture(ByRef) bounds(%11) -> !fir.ref<!fir.array<1024xi32>> {name = "c"}
256   omp.target_enter_data   map_entries(%6, %9, %12 : !fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>)
257   %c1_7 = arith.constant 1 : index
258   %c0_8 = arith.constant 0 : index
259   %13 = arith.subi %c1024, %c1_7 : index
260   %14 = omp.map.bounds   lower_bound(%c0_8 : index) upper_bound(%13 : index) extent(%c1024 : index) stride(%c1_7 : index) start_idx(%c1_7 : index)
261   %15 = omp.map.info var_ptr(%0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>)   map_clauses(from) capture(ByRef) bounds(%14) -> !fir.ref<!fir.array<1024xi32>> {name = "a"}
262   %c1_9 = arith.constant 1 : index
263   %c0_10 = arith.constant 0 : index
264   %16 = arith.subi %c1024_0, %c1_9 : index
265   %17 = omp.map.bounds   lower_bound(%c0_10 : index) upper_bound(%16 : index) extent(%c1024_0 : index) stride(%c1_9 : index) start_idx(%c1_9 : index)
266   %18 = omp.map.info var_ptr(%1 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>)   map_clauses(from) capture(ByRef) bounds(%17) -> !fir.ref<!fir.array<1024xi32>> {name = "b"}
267   %c1_11 = arith.constant 1 : index
268   %c0_12 = arith.constant 0 : index
269   %19 = arith.subi %c1024_1, %c1_11 : index
270   %20 = omp.map.bounds   lower_bound(%c0_12 : index) upper_bound(%19 : index) extent(%c1024_1 : index) stride(%c1_11 : index) start_idx(%c1_11 : index)
271   %21 = omp.map.info var_ptr(%2 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>)   map_clauses(exit_release_or_enter_alloc) capture(ByRef) bounds(%20) -> !fir.ref<!fir.array<1024xi32>> {name = "c"}
272   %c1_13 = arith.constant 1 : index
273   %c0_14 = arith.constant 0 : index
274   %22 = arith.subi %c1024_2, %c1_13 : index
275   %23 = omp.map.bounds   lower_bound(%c0_14 : index) upper_bound(%22 : index) extent(%c1024_2 : index) stride(%c1_13 : index) start_idx(%c1_13 : index)
276   %24 = omp.map.info var_ptr(%3 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>)   map_clauses(always, delete) capture(ByRef) bounds(%23) -> !fir.ref<!fir.array<1024xi32>> {name = "d"}
277   omp.target_exit_data   map_entries(%15, %18, %21, %24 : !fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>, !fir.ref<!fir.array<1024xi32>>)
278   return
281 // CHECK-LABEL:   llvm.func @_QPomp_target_data() {
282 // CHECK:           %[[VAL_1:.*]] = llvm.mlir.constant(1 : i64) : i64
283 // CHECK:           %[[VAL_2:.*]] = llvm.alloca %[[VAL_1]] x !llvm.array<1024 x i32> {bindc_name = "d"} : (i64) -> !llvm.ptr
284 // CHECK:           %[[VAL_3:.*]] = llvm.mlir.constant(1 : i64) : i64
285 // CHECK:           %[[VAL_4:.*]] = llvm.alloca %[[VAL_3]] x !llvm.array<1024 x i32> {bindc_name = "c"} : (i64) -> !llvm.ptr
286 // CHECK:           %[[VAL_5:.*]] = llvm.mlir.constant(1 : i64) : i64
287 // CHECK:           %[[VAL_6:.*]] = llvm.alloca %[[VAL_5]] x !llvm.array<1024 x i32> {bindc_name = "b"} : (i64) -> !llvm.ptr
288 // CHECK:           %[[VAL_7:.*]] = llvm.mlir.constant(1 : i64) : i64
289 // CHECK:           %[[VAL_8:.*]] = llvm.alloca %[[VAL_7]] x !llvm.array<1024 x i32> {bindc_name = "a"} : (i64) -> !llvm.ptr
290 // CHECK:           %[[VAL_0:.*]] = llvm.mlir.constant(1024 : index) : i64
291 // CHECK:           %[[VAL_9:.*]] = llvm.mlir.constant(1024 : index) : i64
292 // CHECK:           %[[VAL_10:.*]] = llvm.mlir.constant(1024 : index) : i64
293 // CHECK:           %[[VAL_11:.*]] = llvm.mlir.constant(1024 : index) : i64
294 // CHECK:           %[[VAL_12:.*]] = llvm.mlir.constant(1 : index) : i64
295 // CHECK:           %[[VAL_13:.*]] = llvm.mlir.constant(0 : index) : i64
296 // CHECK:           %[[VAL_14:.*]] = llvm.mlir.constant(1023 : index) : i64
297 // CHECK:           %[[VAL_15:.*]] = omp.map.bounds lower_bound(%[[VAL_13]] : i64) upper_bound(%[[VAL_14]] : i64) extent(%[[VAL_0]] : i64) stride(%[[VAL_12]] : i64) start_idx(%[[VAL_12]] : i64)
298 // CHECK:           %[[VAL_16:.*]] = omp.map.info var_ptr(%[[VAL_8]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(to) capture(ByRef) bounds(%[[VAL_15]]) -> !llvm.ptr {name = "a"}
299 // CHECK:           %[[VAL_17:.*]] = llvm.mlir.constant(1 : index) : i64
300 // CHECK:           %[[VAL_18:.*]] = llvm.mlir.constant(0 : index) : i64
301 // CHECK:           %[[VAL_19:.*]] = llvm.mlir.constant(1023 : index) : i64
302 // CHECK:           %[[VAL_20:.*]] = omp.map.bounds lower_bound(%[[VAL_18]] : i64) upper_bound(%[[VAL_19]] : i64) extent(%[[VAL_9]] : i64) stride(%[[VAL_17]] : i64) start_idx(%[[VAL_17]] : i64)
303 // CHECK:           %[[VAL_21:.*]] = omp.map.info var_ptr(%[[VAL_6]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(to) capture(ByRef) bounds(%[[VAL_20]]) -> !llvm.ptr {name = "b"}
304 // CHECK:           %[[VAL_22:.*]] = llvm.mlir.constant(1 : index) : i64
305 // CHECK:           %[[VAL_23:.*]] = llvm.mlir.constant(0 : index) : i64
306 // CHECK:           %[[VAL_24:.*]] = llvm.mlir.constant(1023 : index) : i64
307 // CHECK:           %[[VAL_25:.*]] = omp.map.bounds lower_bound(%[[VAL_23]] : i64) upper_bound(%[[VAL_24]] : i64) extent(%[[VAL_10]] : i64) stride(%[[VAL_22]] : i64) start_idx(%[[VAL_22]] : i64)
308 // CHECK:           %[[VAL_26:.*]] = omp.map.info var_ptr(%[[VAL_4]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(always, exit_release_or_enter_alloc) capture(ByRef) bounds(%[[VAL_25]]) -> !llvm.ptr {name = "c"}
309 // CHECK:           omp.target_enter_data map_entries(%[[VAL_16]], %[[VAL_21]], %[[VAL_26]] : !llvm.ptr, !llvm.ptr, !llvm.ptr)
310 // CHECK:           %[[VAL_27:.*]] = llvm.mlir.constant(1 : index) : i64
311 // CHECK:           %[[VAL_28:.*]] = llvm.mlir.constant(0 : index) : i64
312 // CHECK:           %[[VAL_29:.*]] = llvm.mlir.constant(1023 : index) : i64
313 // CHECK:           %[[VAL_30:.*]] = omp.map.bounds lower_bound(%[[VAL_28]] : i64) upper_bound(%[[VAL_29]] : i64) extent(%[[VAL_0]] : i64) stride(%[[VAL_27]] : i64) start_idx(%[[VAL_27]] : i64)
314 // CHECK:           %[[VAL_31:.*]] = omp.map.info var_ptr(%[[VAL_8]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(from) capture(ByRef) bounds(%[[VAL_30]]) -> !llvm.ptr {name = "a"}
315 // CHECK:           %[[VAL_32:.*]] = llvm.mlir.constant(1 : index) : i64
316 // CHECK:           %[[VAL_33:.*]] = llvm.mlir.constant(0 : index) : i64
317 // CHECK:           %[[VAL_34:.*]] = llvm.mlir.constant(1023 : index) : i64
318 // CHECK:           %[[VAL_35:.*]] = omp.map.bounds lower_bound(%[[VAL_33]] : i64) upper_bound(%[[VAL_34]] : i64) extent(%[[VAL_9]] : i64) stride(%[[VAL_32]] : i64) start_idx(%[[VAL_32]] : i64)
319 // CHECK:           %[[VAL_36:.*]] = omp.map.info var_ptr(%[[VAL_6]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(from) capture(ByRef) bounds(%[[VAL_35]]) -> !llvm.ptr {name = "b"}
320 // CHECK:           %[[VAL_37:.*]] = llvm.mlir.constant(1 : index) : i64
321 // CHECK:           %[[VAL_38:.*]] = llvm.mlir.constant(0 : index) : i64
322 // CHECK:           %[[VAL_39:.*]] = llvm.mlir.constant(1023 : index) : i64
323 // CHECK:           %[[VAL_40:.*]] = omp.map.bounds lower_bound(%[[VAL_38]] : i64) upper_bound(%[[VAL_39]] : i64) extent(%[[VAL_10]] : i64) stride(%[[VAL_37]] : i64) start_idx(%[[VAL_37]] : i64)
324 // CHECK:           %[[VAL_41:.*]] = omp.map.info var_ptr(%[[VAL_4]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) bounds(%[[VAL_40]]) -> !llvm.ptr {name = "c"}
325 // CHECK:           %[[VAL_42:.*]] = llvm.mlir.constant(1 : index) : i64
326 // CHECK:           %[[VAL_43:.*]] = llvm.mlir.constant(0 : index) : i64
327 // CHECK:           %[[VAL_44:.*]] = llvm.mlir.constant(1023 : index) : i64
328 // CHECK:           %[[VAL_45:.*]] = omp.map.bounds lower_bound(%[[VAL_43]] : i64) upper_bound(%[[VAL_44]] : i64) extent(%[[VAL_11]] : i64) stride(%[[VAL_42]] : i64) start_idx(%[[VAL_42]] : i64)
329 // CHECK:           %[[VAL_46:.*]] = omp.map.info var_ptr(%[[VAL_2]] : !llvm.ptr, !llvm.array<1024 x i32>) map_clauses(always, delete) capture(ByRef) bounds(%[[VAL_45]]) -> !llvm.ptr {name = "d"}
330 // CHECK:           omp.target_exit_data map_entries(%[[VAL_31]], %[[VAL_36]], %[[VAL_41]], %[[VAL_46]] : !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr)
331 // CHECK:           llvm.return
332 // CHECK:         }
334 // -----
336 func.func @_QPopenmp_target_data_region() {
337   %0 = fir.alloca !fir.array<1024xi32> {bindc_name = "a", uniq_name = "_QFopenmp_target_data_regionEa"}
338   %1 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFopenmp_target_data_regionEi"}
339   %c1024 = arith.constant 1024 : index
340   %c3 = arith.constant 1 : index
341   %c0 = arith.constant 0 : index
342   %c2 = arith.subi %c1024, %c3 : index
343   %bound = omp.map.bounds   lower_bound(%c0 : index) upper_bound(%c2 : index) extent(%c1024 : index) stride(%c3 : index) start_idx(%c3 : index)
344   %entry = omp.map.info var_ptr(%0 : !fir.ref<!fir.array<1024xi32>>, !fir.array<1024xi32>)   map_clauses(tofrom) capture(ByRef) bounds(%bound) -> !fir.ref<!fir.array<1024xi32>> {name = "a"}
345   omp.target_data   map_entries(%entry : !fir.ref<!fir.array<1024xi32>>) {
346     %c1_i32 = arith.constant 1 : i32
347     %2 = fir.convert %c1_i32 : (i32) -> index
348     %c1024_i32 = arith.constant 1024 : i32
349     %3 = fir.convert %c1024_i32 : (i32) -> index
350     %c1 = arith.constant 1 : index
351     %4 = fir.convert %2 : (index) -> i32
352     %5:2 = fir.do_loop %arg0 = %2 to %3 step %c1 iter_args(%arg1 = %4) -> (index, i32) {
353       fir.store %arg1 to %1 : !fir.ref<i32>
354       %6 = fir.load %1 : !fir.ref<i32>
355       %7 = fir.load %1 : !fir.ref<i32>
356       %8 = fir.convert %7 : (i32) -> i64
357       %c1_i64 = arith.constant 1 : i64
358       %9 = arith.subi %8, %c1_i64 : i64
359       %10 = fir.coordinate_of %0, %9 : (!fir.ref<!fir.array<1024xi32>>, i64) -> !fir.ref<i32>
360       fir.store %6 to %10 : !fir.ref<i32>
361       %11 = arith.addi %arg0, %c1 : index
362       %12 = fir.convert %c1 : (index) -> i32
363       %13 = fir.load %1 : !fir.ref<i32>
364       %14 = arith.addi %13, %12 : i32
365       fir.result %11, %14 : index, i32
366     }
367     fir.store %5#1 to %1 : !fir.ref<i32>
368     omp.terminator
369   }
370   return
373 // CHECK-LABEL:   llvm.func @_QPopenmp_target_data_region() {
374 // CHECK:           %[[VAL_2:.*]] = llvm.mlir.constant(1 : i64) : i64
375 // CHECK:           %[[VAL_3:.*]] = llvm.alloca %[[VAL_2]] x i32 {bindc_name = "i"} : (i64) -> !llvm.ptr
376 // CHECK:           %[[VAL_0:.*]] = llvm.mlir.constant(1 : i64) : i64
377 // CHECK:           %[[VAL_1:.*]] = llvm.alloca %[[VAL_0]] x !llvm.array<1024 x i32> {bindc_name = "a"} : (i64) -> !llvm.ptr
378 // CHECK:           %[[VAL_MAX:.*]] = llvm.mlir.constant(1024 : index) : i64
379 // CHECK:           %[[VAL_ONE:.*]] = llvm.mlir.constant(1 : index) : i64
380 // CHECK:           %[[VAL_ZERO:.*]] = llvm.mlir.constant(0 : index) : i64
381 // CHECK:           %[[VAL_UPPER:.*]] = llvm.mlir.constant(1023 : index) : i64
382 // CHECK:           %[[VAL_BOUNDS:.*]] = omp.map.bounds   lower_bound(%[[VAL_ZERO]] : i64) upper_bound(%[[VAL_UPPER]] : i64) extent(%[[VAL_MAX]] : i64) stride(%[[VAL_ONE]] : i64) start_idx(%[[VAL_ONE]] : i64)
383 // CHECK:           %[[VAL_MAP:.*]] = omp.map.info var_ptr(%[[VAL_1]] : !llvm.ptr, !llvm.array<1024 x i32>)  map_clauses(tofrom) capture(ByRef) bounds(%[[VAL_BOUNDS]]) -> !llvm.ptr {name = "a"}
384 // CHECK:           omp.target_data   map_entries(%[[VAL_MAP]] : !llvm.ptr) {
385 // CHECK:             %[[VAL_4:.*]] = llvm.mlir.constant(1 : i32) : i32
386 // CHECK:             %[[VAL_5:.*]] = llvm.sext %[[VAL_4]] : i32 to i64
387 // CHECK:             %[[VAL_6:.*]] = llvm.mlir.constant(1024 : i32) : i32
388 // CHECK:             %[[VAL_7:.*]] = llvm.sext %[[VAL_6]] : i32 to i64
389 // CHECK:             %[[VAL_8:.*]] = llvm.mlir.constant(1 : index) : i64
390 // CHECK:             %[[VAL_9:.*]] = llvm.trunc %[[VAL_5]] : i64 to i32
391 // CHECK:             %[[VAL_10:.*]] = llvm.sub %[[VAL_7]], %[[VAL_5]]  : i64
392 // CHECK:             %[[VAL_11:.*]] = llvm.add %[[VAL_10]], %[[VAL_8]]  : i64
393 // CHECK:             llvm.br ^bb1(%[[VAL_5]], %[[VAL_9]], %[[VAL_11]] : i64, i32, i64)
394 // CHECK:           ^bb1(%[[VAL_12:.*]]: i64, %[[VAL_13:.*]]: i32, %[[VAL_14:.*]]: i64):
395 // CHECK:             %[[VAL_15:.*]] = llvm.mlir.constant(0 : index) : i64
396 // CHECK:             %[[VAL_16:.*]] = llvm.icmp "sgt" %[[VAL_14]], %[[VAL_15]] : i64
397 // CHECK:             llvm.cond_br %[[VAL_16]], ^bb2, ^bb3
398 // CHECK:           ^bb2:
399 // CHECK:             llvm.store %[[VAL_13]], %[[VAL_3]] : i32, !llvm.ptr
400 // CHECK:             %[[VAL_17:.*]] = llvm.load %[[VAL_3]] : !llvm.ptr -> i32
401 // CHECK:             %[[VAL_18:.*]] = llvm.load %[[VAL_3]] : !llvm.ptr -> i32
402 // CHECK:             %[[VAL_19:.*]] = llvm.sext %[[VAL_18]] : i32 to i64
403 // CHECK:             %[[VAL_20:.*]] = llvm.mlir.constant(1 : i64) : i64
404 // CHECK:             %[[VAL_21:.*]] = llvm.sub %[[VAL_19]], %[[VAL_20]]  : i64
405 // CHECK:             %[[VAL_22:.*]] = llvm.getelementptr %[[VAL_1]][0, %[[VAL_21]]] : (!llvm.ptr, i64) -> !llvm.ptr
406 // CHECK:             llvm.store %[[VAL_17]], %[[VAL_22]] : i32, !llvm.ptr
407 // CHECK:             %[[VAL_23:.*]] = llvm.add %[[VAL_12]], %[[VAL_8]]  : i64
408 // CHECK:             %[[VAL_24:.*]] = llvm.trunc %[[VAL_8]] : i64 to i32
409 // CHECK:             %[[VAL_25:.*]] = llvm.load %[[VAL_3]] : !llvm.ptr -> i32
410 // CHECK:             %[[VAL_26:.*]] = llvm.add %[[VAL_25]], %[[VAL_24]]  : i32
411 // CHECK:             %[[VAL_27:.*]] = llvm.add %[[VAL_12]], %[[VAL_8]]  : i64
412 // CHECK:             %[[VAL_28:.*]] = llvm.mlir.constant(1 : index) : i64
413 // CHECK:             %[[VAL_29:.*]] = llvm.sub %[[VAL_14]], %[[VAL_28]]  : i64
414 // CHECK:             llvm.br ^bb1(%[[VAL_27]], %[[VAL_26]], %[[VAL_29]] : i64, i32, i64)
415 // CHECK:           ^bb3:
416 // CHECK:             llvm.store %[[VAL_13]], %[[VAL_3]] : i32, !llvm.ptr
417 // CHECK:             omp.terminator
418 // CHECK:           }
419 // CHECK:           llvm.return
420 // CHECK:         }
422 // -----
424 func.func @_QPomp_target_data_empty() {
425   %0 = fir.alloca !fir.array<1024xi32> {bindc_name = "a", uniq_name = "_QFomp_target_data_emptyEa"}
426   omp.target_data use_device_addr(%0 -> %arg0 : !fir.ref<!fir.array<1024xi32>>) {
427     omp.terminator
428   }
429   return
432 // CHECK-LABEL:   llvm.func @_QPomp_target_data_empty
433 // CHECK: omp.target_data   use_device_addr(%1 -> %{{.*}} : !llvm.ptr) {
434 // CHECK: }
436 // -----
438 func.func @_QPomp_target() {
439   %c512 = arith.constant 512 : index
440   %0 = fir.alloca !fir.array<512xi32> {bindc_name = "a", uniq_name = "_QFomp_targetEa"}
441   %c64_i32 = arith.constant 64 : i32
442   %c1 = arith.constant 1 : index
443   %c0 = arith.constant 0 : index
444   %1 = arith.subi %c512, %c1 : index
445   %2 = omp.map.bounds   lower_bound(%c0 : index) upper_bound(%1 : index) extent(%c512 : index) stride(%c1 : index) start_idx(%c1 : index)
446   %3 = omp.map.info var_ptr(%0 : !fir.ref<!fir.array<512xi32>>, !fir.array<512xi32>)   map_clauses(tofrom) capture(ByRef) bounds(%2) -> !fir.ref<!fir.array<512xi32>> {name = "a"}
447   omp.target   thread_limit(%c64_i32 : i32) map_entries(%3 -> %arg0 : !fir.ref<!fir.array<512xi32>>) {
448     %c10_i32 = arith.constant 10 : i32
449     %c1_i64 = arith.constant 1 : i64
450     %c1_i64_0 = arith.constant 1 : i64
451     %4 = arith.subi %c1_i64, %c1_i64_0 : i64
452     %5 = fir.coordinate_of %arg0, %4 : (!fir.ref<!fir.array<512xi32>>, i64) -> !fir.ref<i32>
453     fir.store %c10_i32 to %5 : !fir.ref<i32>
454     omp.terminator
455   }
456   return
459 // CHECK-LABEL:   llvm.func @_QPomp_target() {
460 // CHECK:           %[[VAL_0:.*]] = llvm.mlir.constant(1 : i64) : i64
461 // CHECK:           %[[VAL_1:.*]] = llvm.alloca %[[VAL_0]] x !llvm.array<512 x i32> {bindc_name = "a"} : (i64) -> !llvm.ptr
462 // CHECK:           %[[EXTENT:.*]] = llvm.mlir.constant(512 : index) : i64
463 // CHECK:           %[[VAL_2:.*]] = llvm.mlir.constant(64 : i32) : i32
464 // CHECK:           %[[STRIDE:.*]] = llvm.mlir.constant(1 : index) : i64
465 // CHECK:           %[[LOWER:.*]] = llvm.mlir.constant(0 : index) : i64
466 // CHECK:           %[[UPPER:.*]] = llvm.mlir.constant(511 : index) : i64
467 // CHECK:           %[[BOUNDS:.*]] = omp.map.bounds   lower_bound(%[[LOWER]] : i64) upper_bound(%[[UPPER]] : i64) extent(%[[EXTENT]] : i64) stride(%[[STRIDE]] : i64) start_idx(%[[STRIDE]] : i64)
468 // CHECK:           %[[MAP:.*]] = omp.map.info var_ptr(%[[VAL_1]] : !llvm.ptr, !llvm.array<512 x i32>)   map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !llvm.ptr {name = "a"}
469 // CHECK:           omp.target thread_limit(%[[VAL_2]] : i32) map_entries(%[[MAP]] -> %[[ARG_0:.*]] : !llvm.ptr) {
470 // CHECK:             %[[VAL_3:.*]] = llvm.mlir.constant(10 : i32) : i32
471 // CHECK:             %[[VAL_4:.*]] = llvm.mlir.constant(1 : i64) : i64
472 // CHECK:             %[[VAL_5:.*]] = llvm.mlir.constant(1 : i64) : i64
473 // CHECK:             %[[VAL_6:.*]] = llvm.mlir.constant(0 : i64) : i64
474 // CHECK:             %[[VAL_7:.*]] = llvm.getelementptr %[[ARG_0]][0, %[[VAL_6]]] : (!llvm.ptr, i64) -> !llvm.ptr
475 // CHECK:             llvm.store %[[VAL_3]], %[[VAL_7]] : i32, !llvm.ptr
476 // CHECK:             omp.terminator
477 // CHECK:           }
478 // CHECK:           llvm.return
479 // CHECK:         }
481 // -----
483 func.func @_QPsimd_with_nested_loop() {
484   %0 = fir.alloca i32 {adapt.valuebyref}
485   %1 = fir.alloca !fir.array<10xi32> {bindc_name = "a", uniq_name = "_QFsimd_with_nested_loopEa"}
486   %2 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsimd_with_nested_loopEi"}
487   %3 = fir.alloca i32 {bindc_name = "j", uniq_name = "_QFsimd_with_nested_loopEj"}
488   %c1_i32 = arith.constant 1 : i32
489   %c10_i32 = arith.constant 10 : i32
490   %c1_i32_0 = arith.constant 1 : i32
491   omp.simd {
492     omp.loop_nest (%arg0) : i32 = (%c1_i32) to (%c10_i32) inclusive step (%c1_i32_0) {
493       fir.store %arg0 to %0 : !fir.ref<i32>
494       %c1_i32_1 = arith.constant 1 : i32
495       %4 = fir.convert %c1_i32_1 : (i32) -> index
496       %c10_i32_2 = arith.constant 10 : i32
497       %5 = fir.convert %c10_i32_2 : (i32) -> index
498       %c1 = arith.constant 1 : index
499       %6 = fir.do_loop %arg1 = %4 to %5 step %c1 -> index {
500         %8 = fir.convert %arg1 : (index) -> i32
501         fir.store %8 to %3 : !fir.ref<i32>
502         %9 = fir.load %0 : !fir.ref<i32>
503         %10 = fir.load %0 : !fir.ref<i32>
504         %11 = fir.convert %10 : (i32) -> i64
505         %c1_i64 = arith.constant 1 : i64
506         %12 = arith.subi %11, %c1_i64 : i64
507         %13 = fir.coordinate_of %1, %12 : (!fir.ref<!fir.array<10xi32>>, i64) -> !fir.ref<i32>
508         fir.store %9 to %13 : !fir.ref<i32>
509         %14 = arith.addi %arg1, %c1 : index
510         fir.result %14 : index
511       }
512       %7 = fir.convert %6 : (index) -> i32
513       fir.store %7 to %3 : !fir.ref<i32>
514       omp.yield
515     }
516   }
517   return
520 // CHECK-LABEL:   llvm.func @_QPsimd_with_nested_loop() {
521 // CHECK:           %[[LOWER:.*]] = llvm.mlir.constant(1 : i32) : i32
522 // CHECK:           %[[UPPER:.*]] = llvm.mlir.constant(10 : i32) : i32
523 // CHECK:           %[[STEP:.*]] = llvm.mlir.constant(1 : i32) : i32
524 // CHECK:           omp.simd {
525 // CHECK-NEXT:        omp.loop_nest (%[[CNT:.*]]) : i32 = (%[[LOWER]]) to (%[[UPPER]]) inclusive step (%[[STEP]]) {
526 // CHECK:               llvm.br ^bb1(%[[VAL_1:.*]], %[[VAL_2:.*]] : i64, i64)
527 // CHECK:             ^bb1(%[[VAL_3:.*]]: i64, %[[VAL_4:.*]]: i64):
528 // CHECK:               %[[VAL_5:.*]] = llvm.mlir.constant(0 : index) : i64
529 // CHECK:               %[[VAL_6:.*]] = llvm.icmp "sgt" %[[VAL_4]], %[[VAL_5]] : i64
530 // CHECK:               llvm.cond_br %[[VAL_6]], ^bb2, ^bb3
531 // CHECK:             ^bb2:
532 // CHECK:               llvm.br ^bb1(%[[VAL_7:.*]], %[[VAL_8:.*]] : i64, i64)
533 // CHECK:             ^bb3:
534 // CHECK:               omp.yield
535 // CHECK:             }
536 // CHECK:           }
537 // CHECK:           llvm.return
538 // CHECK:         }
540 // -----
542 func.func @_QPomp_taskgroup() {
543   omp.taskgroup {
544     omp.task   {
545       fir.call @_QPwork() : () -> ()
546       omp.terminator
547     }
548     omp.terminator
549   }
550   return
552 func.func private @_QPwork()
554 // CHECK-LABEL: llvm.func @_QPomp_taskgroup() {
555 // CHECK:          omp.taskgroup   {
556 // CHECK:            omp.task   {
557 // CHECK:              llvm.call @_QPwork() : () -> ()
558 // CHECK:              omp.terminator
559 // CHECK:            }
560 // CHECK:            omp.terminator
561 // CHECK:          }
562 // CHECK:          llvm.return
563 // CHECK:        }
564 // CHECK:        llvm.func @_QPwork() attributes {sym_visibility = "private"}
565 // CHECK:      }
567 // -----
570 func.func @_QQmain() {
571   %c0 = arith.constant 0 : index
572   %c5 = arith.constant 5 : index
573   %c1 = arith.constant 1 : index
574   %0 = fir.alloca i32
575   omp.taskgroup   {
576     %1 = fir.convert %c1 : (index) -> i32
577     cf.br ^bb1(%1, %c5 : i32, index)
578   ^bb1(%2: i32, %3: index):  // 2 preds: ^bb0, ^bb2
579     %4 = arith.cmpi sgt, %3, %c0 : index
580     cf.cond_br %4, ^bb2, ^bb3
581   ^bb2:  // pred: ^bb1
582     fir.store %2 to %0 : !fir.ref<i32>
583     omp.task   {
584       fir.call @_QFPdo_work(%0) : (!fir.ref<i32>) -> ()
585       omp.terminator
586     }
587     %5 = fir.load %0 : !fir.ref<i32>
588     %6 = arith.addi %5, %1 : i32
589     %7 = arith.subi %3, %c1 : index
590     cf.br ^bb1(%6, %7 : i32, index)
591   ^bb3:  // pred: ^bb1
592     fir.store %2 to %0 : !fir.ref<i32>
593     omp.terminator
594   }
595   return
597 func.func private @_QFPdo_work(!fir.ref<i32>)
599 // CHECK-LABEL: llvm.func @_QQmain
600 // CHECK:          omp.taskgroup   {
601 // CHECK:            omp.task   {
602 // CHECK:              llvm.call @_QFPdo_work({{.*}}) : (!llvm.ptr) -> ()
603 // CHECK:              omp.terminator
604 // CHECK:            }
605 // CHECK:            omp.terminator
606 // CHECK:          }
607 // CHECK:          llvm.return
608 // CHECK:        }
609 // CHECK:        llvm.func @_QFPdo_work(!llvm.ptr)
610 // CHECK:      }
612 // -----
614 func.func @_QPs() {
615   %0 = fir.address_of(@_QFsEc) : !fir.ref<i32>
616   omp.atomic.update   %0 : !fir.ref<i32> {
617   ^bb0(%arg0: i32):
618     %c1_i32 = arith.constant 1 : i32
619     %1 = arith.addi %arg0, %c1_i32 : i32
620     omp.yield(%1 : i32)
621   }
622   return
624 fir.global internal @_QFsEc : i32 {
625   %c10_i32 = arith.constant 10 : i32
626   fir.has_value %c10_i32 : i32
629 // CHECK-LABEL:  llvm.func @_QPs() {
630 // CHECK:    %[[GLOBAL_VAR:.*]] = llvm.mlir.addressof @[[GLOBAL:.*]] : !llvm.ptr
631 // CHECK:    omp.atomic.update   %[[GLOBAL_VAR]] : !llvm.ptr {
632 // CHECK:    ^bb0(%[[IN_VAL:.*]]: i32):
633 // CHECK:      %[[CONST_1:.*]] = llvm.mlir.constant(1 : i32) : i32
634 // CHECK:      %[[OUT_VAL:.*]] = llvm.add %[[IN_VAL]], %[[CONST_1]]  : i32
635 // CHECK:      omp.yield(%[[OUT_VAL]] : i32)
636 // CHECK:    }
637 // CHECK:    llvm.return
638 // CHECK:  }
639 // CHECK:  llvm.mlir.global internal @[[GLOBAL]]() {{.*}} : i32 {
640 // CHECK:    %[[INIT_10:.*]] = llvm.mlir.constant(10 : i32) : i32
641 // CHECK:    llvm.return %[[INIT_10]] : i32
642 // CHECK:  }
644 func.func @_QPsb() {
645   %c10 = arith.constant 10 : index
646   %c1 = arith.constant 1 : index
647   %c1_i32 = arith.constant 1 : i32
648   %c0_i32 = arith.constant 0 : i32
649   %0 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsbEi"}
650   %1 = fir.alloca i32 {bindc_name = "li", uniq_name = "_QFsbEli"}
651   fir.store %c0_i32 to %1 : !fir.ref<i32>
652   omp.sections   {
653     omp.section {
654       %2 = fir.convert %c1 : (index) -> i32
655       %3:2 = fir.do_loop %arg0 = %c1 to %c10 step %c1 iter_args(%arg1 = %2) -> (index, i32) {
656         fir.store %arg1 to %0 : !fir.ref<i32>
657         %4 = fir.load %1 : !fir.ref<i32>
658         %5 = arith.addi %4, %c1_i32 : i32
659         fir.store %5 to %1 : !fir.ref<i32>
660         %6 = arith.addi %arg0, %c1 : index
661         %7 = fir.convert %c1 : (index) -> i32
662         %8 = fir.load %0 : !fir.ref<i32>
663         %9 = arith.addi %8, %7 : i32
664         fir.result %6, %9 : index, i32
665       }
666       fir.store %3#1 to %0 : !fir.ref<i32>
667       omp.terminator
668     }
669     omp.terminator
670   }
671   return
674 // CHECK:  llvm.func @_QPsb() {
675 // CHECK:    %[[SIZE:.*]] = llvm.mlir.constant(1 : i64) : i64
676 // CHECK:    %[[LI_REF:.*]] = llvm.alloca %[[SIZE]] x i32 {bindc_name = "li"} : (i64) -> !llvm.ptr
677 // CHECK:    %[[ONE:.*]] = llvm.mlir.constant(1 : i32) : i32
678 // CHECK:    omp.sections   {
679 // CHECK:      omp.section {
680 // CHECK:        llvm.br ^[[BB_ENTRY:.*]]({{.*}})
681 // CHECK:      ^[[BB_ENTRY]]({{.*}}):
682 // CHECK:        %[[EXIT_COND:.*]] = llvm.icmp "sgt"
683 // CHECK:        llvm.cond_br %[[EXIT_COND]], ^[[BB_LOOP_BODY:.*]], ^[[BB_EXIT:.*]]
684 // CHECK:      ^[[BB_LOOP_BODY]]:
685 // CHECK:        %[[LI_VAL:.*]] = llvm.load %[[LI_REF]] : !llvm.ptr -> i32
686 // CHECK:        %[[LI_INC:.*]] = llvm.add %[[LI_VAL]], %[[ONE]]  : i32
687 // CHECK:        llvm.store %[[LI_INC]], %[[LI_REF]] : i32, !llvm.ptr
688 // CHECK:        llvm.br ^[[BB_ENTRY]]({{.*}})
689 // CHECK:      ^[[BB_EXIT]]:
690 // CHECK:        omp.terminator
691 // CHECK:      }
692 // CHECK:      omp.terminator
693 // CHECK:    }
694 // CHECK:    llvm.return
695 // CHECK:  }
697 // -----
699 // CHECK:  omp.declare_reduction @[[EQV_REDUCTION:.*]] : i32 init {
700 // CHECK:  ^bb0(%{{.*}}: i32):
701 // CHECK:    %[[TRUE:.*]] = llvm.mlir.constant(1 : i64) : i32
702 // CHECK:    omp.yield(%[[TRUE]] : i32)
703 // CHECK:  } combiner {
704 // CHECK:  ^bb0(%[[ARG_1:.*]]: i32, %[[ARG_2:.*]]: i32):
705 // CHECK:    %[[ZERO_1:.*]] = llvm.mlir.constant(0 : i64) : i32
706 // CHECK:    %[[ARGVAL_1:.*]] = llvm.icmp "ne" %[[ARG_1]], %[[ZERO_1]] : i32
707 // CHECK:    %[[ZERO_2:.*]] = llvm.mlir.constant(0 : i64) : i32
708 // CHECK:    %[[ARGVAL_2:.*]] = llvm.icmp "ne" %[[ARG_2]], %[[ZERO_2]] : i32
709 // CHECK:    %[[RES:.*]] = llvm.icmp "eq" %[[ARGVAL_1]], %[[ARGVAL_2]] : i1
710 // CHECK:    %[[RES_EXT:.*]] = llvm.zext %[[RES]] : i1 to i32
711 // CHECK:    omp.yield(%[[RES_EXT]] : i32)
712 // CHECK:  }
713 // CHECK-LABEL:  @_QPsimple_reduction
714 // CHECK-SAME: %[[ARRAY_REF:.*]]: !llvm.ptr
715 // CHECK:    %[[VAL_1:.*]] = llvm.mlir.constant(1 : i64) : i64
716 // CHECK:    %[[RED_ACCUMULATOR:.*]] = llvm.alloca %[[VAL_1]] x i32 {bindc_name = "x"} : (i64) -> !llvm.ptr
717 // CHECK:    omp.parallel   {
718 // CHECK:      omp.wsloop reduction(@[[EQV_REDUCTION]] %[[RED_ACCUMULATOR]] -> %[[PRV:.+]] : !llvm.ptr) {
719 // CHECK-NEXT:   omp.loop_nest
720 // CHECK:          %[[ARRAY_ELEM_REF:.*]] = llvm.getelementptr %[[ARRAY_REF]][0, %{{.*}}] : (!llvm.ptr, i64) -> !llvm.ptr
721 // CHECK:          %[[ARRAY_ELEM:.*]] = llvm.load %[[ARRAY_ELEM_REF]] : !llvm.ptr -> i32
722 // CHECK:          %[[LPRV:.+]] = llvm.load %[[PRV]] : !llvm.ptr -> i32
723 // CHECK:          %[[ZERO_1:.*]] = llvm.mlir.constant(0 : i64) : i32
724 // CHECK:          %[[ARGVAL_1:.*]] = llvm.icmp "ne" %[[LPRV]], %[[ZERO_1]] : i32
725 // CHECK:          %[[ZERO_2:.*]] = llvm.mlir.constant(0 : i64) : i32
726 // CHECK:          %[[ARGVAL_2:.*]] = llvm.icmp "ne" %[[ARRAY_ELEM]], %[[ZERO_2]] : i32
727 // CHECK:          %[[RES:.*]] = llvm.icmp "eq" %[[ARGVAL_2]], %[[ARGVAL_1]] : i1
728 // CHECK:          %[[RES_EXT:.*]] = llvm.zext %[[RES]] : i1 to i32
729 // CHECK:          llvm.store %[[RES_EXT]], %[[PRV]] : i32, !llvm.ptr
730 // CHECK:          omp.yield
731 // CHECK:      omp.terminator
732 // CHECK:    llvm.return
734 omp.declare_reduction @eqv_reduction : !fir.logical<4> init {
735 ^bb0(%arg0: !fir.logical<4>):
736   %true = arith.constant true
737   %0 = fir.convert %true : (i1) -> !fir.logical<4>
738   omp.yield(%0 : !fir.logical<4>)
739 } combiner {
740 ^bb0(%arg0: !fir.logical<4>, %arg1: !fir.logical<4>):
741   %0 = fir.convert %arg0 : (!fir.logical<4>) -> i1
742   %1 = fir.convert %arg1 : (!fir.logical<4>) -> i1
743   %2 = arith.cmpi eq, %0, %1 : i1
744   %3 = fir.convert %2 : (i1) -> !fir.logical<4>
745   omp.yield(%3 : !fir.logical<4>)
747 func.func @_QPsimple_reduction(%arg0: !fir.ref<!fir.array<100x!fir.logical<4>>> {fir.bindc_name = "y"}) {
748   %0 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsimple_reductionEi"}
749   %1 = fir.alloca !fir.logical<4> {bindc_name = "x", uniq_name = "_QFsimple_reductionEx"}
750   %true = arith.constant true
751   %2 = fir.convert %true : (i1) -> !fir.logical<4>
752   fir.store %2 to %1 : !fir.ref<!fir.logical<4>>
753   omp.parallel   {
754     %3 = fir.alloca i32 {adapt.valuebyref, pinned}
755     %c1_i32 = arith.constant 1 : i32
756     %c100_i32 = arith.constant 100 : i32
757     %c1_i32_0 = arith.constant 1 : i32
758     omp.wsloop reduction(@eqv_reduction %1 -> %prv : !fir.ref<!fir.logical<4>>) {
759       omp.loop_nest (%arg1) : i32 = (%c1_i32) to (%c100_i32) inclusive step (%c1_i32_0) {
760         fir.store %arg1 to %3 : !fir.ref<i32>
761         %4 = fir.load %3 : !fir.ref<i32>
762         %5 = fir.convert %4 : (i32) -> i64
763         %c1_i64 = arith.constant 1 : i64
764         %6 = arith.subi %5, %c1_i64 : i64
765         %7 = fir.coordinate_of %arg0, %6 : (!fir.ref<!fir.array<100x!fir.logical<4>>>, i64) -> !fir.ref<!fir.logical<4>>
766         %8 = fir.load %7 : !fir.ref<!fir.logical<4>>
767         %lprv = fir.load %prv : !fir.ref<!fir.logical<4>>
768         %lprv1 = fir.convert %lprv : (!fir.logical<4>) -> i1
769         %9 = fir.convert %8 : (!fir.logical<4>) -> i1
770         %10 = arith.cmpi eq, %9, %lprv1 : i1
771         %11 = fir.convert %10 : (i1) -> !fir.logical<4>
772         fir.store %11 to %prv : !fir.ref<!fir.logical<4>>
773         omp.yield
774       }
775     }
776     omp.terminator
777   }
778   return
781 // -----
783 // CHECK: llvm.func @_QPs
784 // CHECK: omp.atomic.read %{{.*}} = %{{.*}}   : !llvm.ptr, !llvm.ptr, !llvm.struct<(f32, f32)>
786 func.func @_QPs(%arg0: !fir.ref<complex<f32>> {fir.bindc_name = "x"}) {
787   %0 = fir.alloca complex<f32> {bindc_name = "v", uniq_name = "_QFsEv"}
788   omp.atomic.read %0 = %arg0   : !fir.ref<complex<f32>>, !fir.ref<complex<f32>>, complex<f32>
789   return
792 // -----
794 // Test if llvm.alloca is properly inserted in the omp section
796 //CHECK:  %[[CONST0:.*]] = llvm.mlir.constant(1 : i64) : i64
797 //CHECK:  %[[CONST:.*]] = llvm.mlir.constant(1 : i64) : i64
798 //CHECK:  %[[ALLOCA:.*]] = llvm.alloca %[[CONST]] x !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)> {bindc_name = "iattr"} : (i64) -> !llvm.ptr
799 //CHECK:  omp.parallel   {
800 //CHECK:    %[[CONST_1:.*]] = llvm.mlir.constant(1 : i32) : i32
801 //CHECK:    %[[ALLOCA_1:.*]] = llvm.alloca %[[CONST_1:.*]] x !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)> {alignment = 8 : i64} : (i32) -> !llvm.ptr
802 //CHECK:    %[[SIZE:.*]] = llvm.mlir.constant(24 : i32) : i32
803 //CHECK:    "llvm.intr.memcpy"(%[[ALLOCA_1]], %[[ALLOCA]], %[[SIZE]]) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> ()
804 //CHECK:    %[[GEP:.*]] = llvm.getelementptr %[[ALLOCA_1]][0, 0] : (!llvm.ptr) -> !llvm.ptr
805 //CHECK:    %[[LOAD_2:.*]] = llvm.load %[[GEP]] : !llvm.ptr -> !llvm.ptr
806 //CHECK:    omp.terminator
807 //CHECK:  }
809 func.func @_QQmain() attributes {fir.bindc_name = "mn"} {
810   %0 = fir.alloca !fir.box<!fir.ptr<i32>> {bindc_name = "iattr", uniq_name = "_QFEiattr"}
811   %1 = fir.zero_bits !fir.ptr<i32>
812   %2 = fir.embox %1 : (!fir.ptr<i32>) -> !fir.box<!fir.ptr<i32>>
813   fir.store %2 to %0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
814   %3 = fir.address_of(@_QFEx) : !fir.ref<i32>
815   %4 = fir.alloca i32 {bindc_name = "y", uniq_name = "_QFEy"}
816   %5 = fir.embox %3 : (!fir.ref<i32>) -> !fir.box<!fir.ptr<i32>>
817   fir.store %5 to %0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
818   omp.parallel   {
819     %6 = fir.load %4 : !fir.ref<i32>
820     %7 = fir.load %0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
821     %8 = fir.box_addr %7 : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
822     fir.store %6 to %8 : !fir.ptr<i32>
823     omp.terminator
824   }
825   return
827 fir.global internal @_QFEx target : i32 {
828   %0 = fir.zero_bits i32
829   fir.has_value %0 : i32
832 // -----
834 // Test if llvm.alloca is properly inserted in the omp ordered region
836 // CHECK: llvm.func @sub_
837 func.func @sub_() {
838   %c0 = arith.constant 0 : index
839   %c1 = arith.constant 1 : index
840   %0 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsubEi"}
841 // CHECK: omp.ordered.region
842   omp.ordered.region {
843     %1 = fir.convert %c1 : (index) -> i32
844     cf.br ^bb1(%1, %c1 : i32, index)
845   ^bb1(%2: i32, %3: index):  // 2 preds: ^bb0, ^bb2
846     %4 = arith.cmpi sgt, %3, %c0 : index
847     cf.cond_br %4, ^bb2, ^bb3
848   ^bb2:  // pred: ^bb1
849     fir.store %2 to %0 : !fir.ref<i32>
850     %5 = fir.load %0 : !fir.ref<i32>
851 // CHECK: llvm.add
852     %6 = arith.addi %5, %1 : i32
853 // CHECK: llvm.sub
854     %7 = arith.subi %3, %c1 : index
855     cf.br ^bb1(%6, %7 : i32, index)
856   ^bb3:  // pred: ^bb1
857     fir.store %2 to %0 : !fir.ref<i32>
858 // CHECK: omp.terminator
859     omp.terminator
860   }
861   return
864 // -----
866 // CHECK-LABEL:  llvm.func @flush_standalone_
867 // CHECK-SAME:   %[[ARG_A:.*]]: !llvm.ptr {fir.bindc_name = "a"}, %[[ARG_B:.*]]: !llvm.ptr {fir.bindc_name = "b"}, %[[ARG_C:.*]]: !llvm.ptr {fir.bindc_name = "c"})
868   func.func @flush_standalone_(%arg0: !fir.ref<i32> {fir.bindc_name = "a"}, %arg1: !fir.ref<i32> {fir.bindc_name = "b"}, %arg2: !fir.ref<i32> {fir.bindc_name = "c"}) {
869 // CHECK:   omp.flush(%[[ARG_A]], %[[ARG_B]], %[[ARG_C]] : !llvm.ptr, !llvm.ptr, !llvm.ptr)
870     omp.flush(%arg0, %arg1, %arg2 : !fir.ref<i32>, !fir.ref<i32>, !fir.ref<i32>)
871 // CHECK:   omp.flush
872     omp.flush
873     return
874   }
876 // CHECK-LABEL:  llvm.func @flush_parallel_
877 // CHECK-SAME:   %[[ARG_A:.*]]: !llvm.ptr {fir.bindc_name = "a"}, %[[ARG_B:.*]]: !llvm.ptr {fir.bindc_name = "b"}, %[[ARG_C:.*]]: !llvm.ptr {fir.bindc_name = "c"})
878   func.func @flush_parallel_(%arg0: !fir.ref<i32> {fir.bindc_name = "a"}, %arg1: !fir.ref<i32> {fir.bindc_name = "b"}, %arg2: !fir.ref<i32> {fir.bindc_name = "c"}) {
879 // CHECK:    omp.parallel   {
880     omp.parallel   {
881 // CHECK:      omp.flush(%[[ARG_A]], %[[ARG_B]], %[[ARG_C]] : !llvm.ptr, !llvm.ptr, !llvm.ptr)
882       omp.flush(%arg0, %arg1, %arg2 : !fir.ref<i32>, !fir.ref<i32>, !fir.ref<i32>)
883 // CHECK:      omp.flush
884       omp.flush
885 // CHECK:      %[[A_VAL:.*]] = llvm.load %[[ARG_A]] : !llvm.ptr -> i32
886       %0 = fir.load %arg0 : !fir.ref<i32>
887 // CHECK:      %[[B_VAL:.*]] = llvm.load %[[ARG_B]] : !llvm.ptr -> i32
888       %1 = fir.load %arg1 : !fir.ref<i32>
889 // CHECK:      %[[C_VAL:.*]] = llvm.add %[[A_VAL]], %[[B_VAL]]  : i32
890       %2 = arith.addi %0, %1 : i32
891 // CHECK:      llvm.store %[[C_VAL]], %[[ARG_C]] : i32, !llvm.ptr
892       fir.store %2 to %arg2 : !fir.ref<i32>
893 // CHECK:      omp.terminator
894       omp.terminator
895 // CHECK:    }
896     }
897     return
898   }
900 // -----
902 // CHECK:  omp.critical.declare @help   hint(contended)
903 omp.critical.declare @help hint(contended)
905 // CHECK: llvm.func @omp_critical_() {
906 func.func @omp_critical_() {
907 // CHECK: %[[Y_REF:.*]] = llvm.alloca %{{.*}} x i32 {bindc_name = "y"} : (i64) -> !llvm.ptr
908   %0 = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFomp_criticalEx"}
909 // CHECK: %[[X_REF:.*]] = llvm.alloca %{{.*}} x i32 {bindc_name = "x"} : (i64) -> !llvm.ptr
910   %1 = fir.alloca i32 {bindc_name = "y", uniq_name = "_QFomp_criticalEy"}
911 // CHECK: omp.critical(@help)
912   omp.critical(@help) {
913 // CHECK: %[[X_VAL:.*]] = llvm.load %[[X_REF]] : !llvm.ptr -> i32
914     %2 = fir.load %0 : !fir.ref<i32>
915 // CHECK: %[[Y_VAL:.*]] = llvm.load %[[Y_REF]] : !llvm.ptr -> i32
916     %3 = fir.load %1 : !fir.ref<i32>
917 // CHECK: %[[RESULT:.*]] = llvm.add %[[X_VAL]], %[[Y_VAL]]  : i32
918     %4 = arith.addi %2, %3 : i32
919 // CHECK: llvm.store %[[RESULT]], %[[X_REF]] : i32, !llvm.ptr
920     fir.store %4 to %0 : !fir.ref<i32>
921 // CHECK: omp.terminator
922     omp.terminator
923   }
924   return
927 // -----
929 // CHECK-LABEL:  llvm.func @omp_map_info_descriptor_type_conversion
930 // CHECK-SAME:   %[[ARG_0:.*]]: !llvm.ptr)
932 func.func @omp_map_info_descriptor_type_conversion(%arg0 : !fir.ref<!fir.box<!fir.heap<i32>>>) {
933   // CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ARG_0]][0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)>
934   %0 = fir.box_offset %arg0 base_addr : (!fir.ref<!fir.box<!fir.heap<i32>>>) -> !fir.llvm_ptr<!fir.ref<i32>>
935   // CHECK: %[[MEMBER_MAP:.*]] = omp.map.info var_ptr(%[[GEP]] : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""}
936   %1 = omp.map.info var_ptr(%0 : !fir.llvm_ptr<!fir.ref<i32>>, i32) map_clauses(tofrom) capture(ByRef) -> !fir.llvm_ptr<!fir.ref<i32>> {name = ""}
937   // CHECK: %[[DESC_MAP:.*]] = omp.map.info var_ptr(%[[ARG_0]] : !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)>) map_clauses(always, delete) capture(ByRef) members(%[[MEMBER_MAP]] : [0] : !llvm.ptr) -> !llvm.ptr {name = ""}
938   %2 = omp.map.info var_ptr(%arg0 : !fir.ref<!fir.box<!fir.heap<i32>>>, !fir.box<!fir.heap<i32>>) map_clauses(always, delete) capture(ByRef) members(%1 : [0] : !fir.llvm_ptr<!fir.ref<i32>>) -> !fir.ref<!fir.box<!fir.heap<i32>>> {name = ""}
939   // CHECK: omp.target_exit_data map_entries(%[[DESC_MAP]] : !llvm.ptr) 
940   omp.target_exit_data   map_entries(%2 : !fir.ref<!fir.box<!fir.heap<i32>>>)
941   return 
944 // -----
946 // CHECK-LABEL:  llvm.func @omp_map_info_derived_type_explicit_member_conversion
947 // CHECK-SAME:   %[[ARG_0:.*]]: !llvm.ptr)
949 func.func @omp_map_info_derived_type_explicit_member_conversion(%arg0 : !fir.ref<!fir.type<_QFderived_type{real:f32,array:!fir.array<10xi32>,int:i32}>>) {
950   // CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ARG_0]][0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"_QFderived_type", (f32, array<10 x i32>, i32)>
951   %0 = fir.field_index int, !fir.type<_QFderived_type{real:f32,array:!fir.array<10xi32>,int:i32}>
952   %1 = fir.coordinate_of %arg0, %0 : (!fir.ref<!fir.type<_QFderived_type{real:f32,array:!fir.array<10xi32>,int:i32}>>, !fir.field) -> !fir.ref<i32>
953   // CHECK: %[[MAP_MEMBER_1:.*]] = omp.map.info var_ptr(%[[GEP]] : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = "dtype%int"}
954   %2 = omp.map.info var_ptr(%1 : !fir.ref<i32>, i32) map_clauses(tofrom) capture(ByRef) -> !fir.ref<i32> {name = "dtype%int"}
955   // CHECK: %[[GEP_2:.*]] = llvm.getelementptr %[[ARG_0]][0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"_QFderived_type", (f32, array<10 x i32>, i32)>
956   %3 = fir.field_index real, !fir.type<_QFderived_type{real:f32,array:!fir.array<10xi32>,int:i32}>
957   %4 = fir.coordinate_of %arg0, %3 : (!fir.ref<!fir.type<_QFderived_type{real:f32,array:!fir.array<10xi32>,int:i32}>>, !fir.field) -> !fir.ref<f32>
958   // CHECK: %[[MAP_MEMBER_2:.*]] = omp.map.info var_ptr(%[[GEP_2]] : !llvm.ptr, f32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = "dtype%real"}
959   %5 = omp.map.info var_ptr(%4 : !fir.ref<f32>, f32) map_clauses(tofrom) capture(ByRef) -> !fir.ref<f32> {name = "dtype%real"}    
960   // CHECK: %[[MAP_PARENT:.*]] = omp.map.info var_ptr(%[[ARG_0]] : !llvm.ptr, !llvm.struct<"_QFderived_type", (f32, array<10 x i32>, i32)>) map_clauses(tofrom) capture(ByRef) members(%[[MAP_MEMBER_1]], %[[MAP_MEMBER_2]] : [2], [0] : !llvm.ptr, !llvm.ptr) -> !llvm.ptr {name = "dtype", partial_map = true} 
961   %6 = omp.map.info var_ptr(%arg0 : !fir.ref<!fir.type<_QFderived_type{real:f32,array:!fir.array<10xi32>,int:i32}>>, !fir.type<_QFderived_type{real:f32,array:!fir.array<10xi32>,int:i32}>) map_clauses(tofrom) capture(ByRef) members(%2, %5 : [2], [0] : !fir.ref<i32>, !fir.ref<f32>) -> !fir.ref<!fir.type<_QFderived_type{real:f32,array:!fir.array<10xi32>,int:i32}>> {name = "dtype", partial_map = true}
962   // CHECK: omp.target map_entries(%[[MAP_MEMBER_1]] -> %[[ARG_1:.*]], %[[MAP_MEMBER_2]] -> %[[ARG_2:.*]], %[[MAP_PARENT]] -> %[[ARG_3:.*]] : !llvm.ptr, !llvm.ptr, !llvm.ptr) {
963   omp.target map_entries(%2 -> %arg1, %5 -> %arg2, %6 -> %arg3 : !fir.ref<i32>, !fir.ref<f32>, !fir.ref<!fir.type<_QFderived_type{real:f32,array:!fir.array<10xi32>,int:i32}>>) {
964     omp.terminator
965   }
966   return
969 // -----
971 // CHECK-LABEL:  llvm.func @omp_map_info_nested_derived_type_explicit_member_conversion
972 // CHECK-SAME:   %[[ARG_0:.*]]: !llvm.ptr)
974 func.func @omp_map_info_nested_derived_type_explicit_member_conversion(%arg0 : !fir.ref<!fir.type<_QFTtop_layer{array_i:!fir.array<10xi32>,nested:!fir.type<_QFTbottom_layer{array_i2:!fir.array<10xf32>,i2:f64}>,k:i32}>>) {
975     // CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ARG_0]][0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"_QFTtop_layer", (array<10 x i32>, struct<"_QFTbottom_layer", (array<10 x f32>, f64)>, i32)>
976     %0 = fir.field_index nested, !fir.type<_QFTtop_layer{array_i:!fir.array<10xi32>,nested:!fir.type<_QFTbottom_layer{array_i2:!fir.array<10xf32>,i2:f64}>,k:i32}>
977     %1 = fir.coordinate_of %arg0, %0 : (!fir.ref<!fir.type<_QFTtop_layer{array_i:!fir.array<10xi32>,nested:!fir.type<_QFTbottom_layer{array_i2:!fir.array<10xf32>,i2:f64}>,k:i32}>>, !fir.field) -> !fir.ref<!fir.type<_QFTbottom_layer{array_i2:!fir.array<10xf32>,i2:f64}>>
978     // CHECK: %[[GEP_2:.*]] = llvm.getelementptr %[[GEP]][0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"_QFTbottom_layer", (array<10 x f32>, f64)>
979     %2 = fir.field_index i2, !fir.type<_QFTbottom_layer{array_i2:!fir.array<10xf32>,i2:f64}>
980     %3 = fir.coordinate_of %1, %2 : (!fir.ref<!fir.type<_QFTbottom_layer{array_i2:!fir.array<10xf32>,i2:f64}>>, !fir.field) -> !fir.ref<f64>
981     // CHECK: %[[MAP_MEMBER_1:.*]] = omp.map.info var_ptr(%[[GEP_2]] : !llvm.ptr, f64) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr
982     %4 = omp.map.info var_ptr(%3 : !fir.ref<f64>, f64) map_clauses(tofrom) capture(ByRef) -> !fir.ref<f64>
983     // CHECK: %[[GEP_3:.*]] = llvm.getelementptr %[[ARG_0]][0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"_QFTtop_layer", (array<10 x i32>, struct<"_QFTbottom_layer", (array<10 x f32>, f64)>, i32)>
984     %5 = fir.field_index k, !fir.type<_QFTtop_layer{array_i:!fir.array<10xi32>,nested:!fir.type<_QFTbottom_layer{array_i2:!fir.array<10xf32>,i2:f64}>,k:i32}>
985     %6 = fir.coordinate_of %arg0, %5 : (!fir.ref<!fir.type<_QFTtop_layer{array_i:!fir.array<10xi32>,nested:!fir.type<_QFTbottom_layer{array_i2:!fir.array<10xf32>,i2:f64}>,k:i32}>>, !fir.field) -> !fir.ref<i32>
986     // CHECK: %[[MAP_MEMBER_2:.*]] = omp.map.info var_ptr(%[[GEP_3]] : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr
987     %7 = omp.map.info var_ptr(%6 : !fir.ref<i32>, i32) map_clauses(tofrom) capture(ByRef) -> !fir.ref<i32>
988     // CHECK: %[[PARENT_MAP:.*]] = omp.map.info var_ptr(%[[ARG_0]] : !llvm.ptr, !llvm.struct<"_QFTtop_layer", (array<10 x i32>, struct<"_QFTbottom_layer", (array<10 x f32>, f64)>, i32)>) map_clauses(tofrom) capture(ByRef) members(%[[MAP_MEMBER_1]], %[[MAP_MEMBER_2]] : [1, 1], [2] : !llvm.ptr, !llvm.ptr) -> !llvm.ptr {partial_map = true}
989     %9 = omp.map.info var_ptr(%arg0 : !fir.ref<!fir.type<_QFTtop_layer{array_i:!fir.array<10xi32>,nested:!fir.type<_QFTbottom_layer{array_i2:!fir.array<10xf32>,i2:f64}>,k:i32}>>, !fir.type<_QFTtop_layer{array_i:!fir.array<10xi32>,nested:!fir.type<_QFTbottom_layer{array_i2:!fir.array<10xf32>,i2:f64}>,k:i32}>) map_clauses(tofrom) capture(ByRef) members(%4, %7 : [1,1], [2] : !fir.ref<f64>, !fir.ref<i32>) -> !fir.ref<!fir.type<_QFTtop_layer{array_i:!fir.array<10xi32>,nested:!fir.type<_QFTbottom_layer{array_i2:!fir.array<10xf32>,i2:f64}>,k:i32}>> {partial_map = true}
990     // CHECK: omp.target map_entries(%[[MAP_MEMBER_1]] -> %{{.*}}, %[[MAP_MEMBER_2]] -> %{{.*}}, %[[PARENT_MAP]] -> %{{.*}} : !llvm.ptr, !llvm.ptr, !llvm.ptr) {
991     omp.target map_entries(%4 -> %arg1, %7 -> %arg2, %9 -> %arg3 : !fir.ref<f64>, !fir.ref<i32>, !fir.ref<!fir.type<_QFTtop_layer{array_i:!fir.array<10xi32>,nested:!fir.type<_QFTbottom_layer{array_i2:!fir.array<10xf32>,i2:f64}>,k:i32}>>) {
992       omp.terminator
993     }
994   return
997 // -----
999 // CHECK-LABEL:  llvm.func @omp_map_common_block_using_common_block_symbol
1001 // CHECK: %[[ADDR_OF:.*]] = llvm.mlir.addressof @var_common_ : !llvm.ptr
1002 // CHECK: %[[CB_MAP:.*]] = omp.map.info var_ptr(%[[ADDR_OF]] : !llvm.ptr, !llvm.array<8 x i8>) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = "var_common"}
1003 // CHECK:    omp.target map_entries(%[[CB_MAP]] -> %[[ARG0:.*]] : !llvm.ptr) {
1004 // CHECK:      %[[VAR_2_OFFSET:.*]] = llvm.mlir.constant(4 : index) : i64
1005 // CHECK:      %[[VAR_1_OFFSET:.*]] = llvm.mlir.constant(0 : index) : i64
1006 // CHECK:      %{{.*}} = llvm.getelementptr %[[ARG0]][%[[VAR_1_OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i8
1007 // CHECK:      %{{.*}} = llvm.getelementptr %[[ARG0]][%[[VAR_2_OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i8
1009 func.func @omp_map_common_block_using_common_block_symbol() {
1010   %0 = fir.address_of(@var_common_) : !fir.ref<!fir.array<8xi8>>
1011   %1 = omp.map.info var_ptr(%0 : !fir.ref<!fir.array<8xi8>>, !fir.array<8xi8>) map_clauses(tofrom) capture(ByRef) -> !fir.ref<!fir.array<8xi8>> {name = "var_common"}
1012   omp.target map_entries(%1 -> %arg0 : !fir.ref<!fir.array<8xi8>>) {
1013     %c4 = arith.constant 4 : index
1014     %c0 = arith.constant 0 : index
1015     %c20_i32 = arith.constant 20 : i32
1016     %2 = fir.convert %arg0 : (!fir.ref<!fir.array<8xi8>>) -> !fir.ref<!fir.array<?xi8>>
1017     %3 = fir.coordinate_of %2, %c0 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
1018     %4 = fir.convert %3 : (!fir.ref<i8>) -> !fir.ref<i32>
1019     %5 = fir.convert %arg0 : (!fir.ref<!fir.array<8xi8>>) -> !fir.ref<!fir.array<?xi8>>
1020     %6 = fir.coordinate_of %5, %c4 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
1021     %7 = fir.convert %6 : (!fir.ref<i8>) -> !fir.ref<i32>
1022     %8 = fir.load %4 : !fir.ref<i32>
1023     %9 = arith.addi %8, %c20_i32 : i32
1024     fir.store %9 to %7 : !fir.ref<i32>
1025     omp.terminator
1026   }
1027   return
1030 fir.global common @var_common_(dense<0> : vector<8xi8>) {alignment = 4 : i64} : !fir.array<8xi8>
1032 // -----
1034 // CHECK-LABEL:  llvm.func @omp_map_common_block_using_common_block_members
1036 // CHECK:    %[[VAR_2_OFFSET:.*]] = llvm.mlir.constant(4 : index) : i64
1037 // CHECK:    %[[VAR_1_OFFSET:.*]] = llvm.mlir.constant(0 : index) : i64
1038 // CHECK:    %[[ADDR_OF:.*]] = llvm.mlir.addressof @var_common_ : !llvm.ptr
1039 // CHECK:    %[[VAR_1_CB_GEP:.*]] = llvm.getelementptr %[[ADDR_OF]][%[[VAR_1_OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i8
1040 // CHECK:    %[[VAR_2_CB_GEP:.*]] = llvm.getelementptr %[[ADDR_OF]][%[[VAR_2_OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i8
1041 // CHECK:    %[[MAP_CB_VAR_1:.*]] = omp.map.info var_ptr(%[[VAR_1_CB_GEP]] : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = "var1"}
1042 // CHECK:    %[[MAP_CB_VAR_2:.*]] = omp.map.info var_ptr(%[[VAR_2_CB_GEP]] : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = "var2"}
1043 // CHECK:    omp.target map_entries(%[[MAP_CB_VAR_1]] -> %[[ARG0:.*]], %[[MAP_CB_VAR_2]] -> %[[ARG1:.*]] : !llvm.ptr, !llvm.ptr) {
1045 func.func @omp_map_common_block_using_common_block_members() {
1046   %c4 = arith.constant 4 : index
1047   %c0 = arith.constant 0 : index
1048   %0 = fir.address_of(@var_common_) : !fir.ref<!fir.array<8xi8>>
1049   %1 = fir.convert %0 : (!fir.ref<!fir.array<8xi8>>) -> !fir.ref<!fir.array<?xi8>>
1050   %2 = fir.coordinate_of %1, %c0 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
1051   %3 = fir.convert %2 : (!fir.ref<i8>) -> !fir.ref<i32>
1052   %4 = fir.convert %0 : (!fir.ref<!fir.array<8xi8>>) -> !fir.ref<!fir.array<?xi8>>
1053   %5 = fir.coordinate_of %4, %c4 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
1054   %6 = fir.convert %5 : (!fir.ref<i8>) -> !fir.ref<i32>
1055   %7 = omp.map.info var_ptr(%3 : !fir.ref<i32>, i32) map_clauses(tofrom) capture(ByRef) -> !fir.ref<i32> {name = "var1"}
1056   %8 = omp.map.info var_ptr(%6 : !fir.ref<i32>, i32) map_clauses(tofrom) capture(ByRef) -> !fir.ref<i32> {name = "var2"}
1057   omp.target map_entries(%7 -> %arg0, %8 -> %arg1 : !fir.ref<i32>, !fir.ref<i32>) {
1058     %c10_i32 = arith.constant 10 : i32
1059     %9 = fir.load %arg0 : !fir.ref<i32>
1060     %10 = arith.muli %9, %c10_i32 : i32
1061     fir.store %10 to %arg1 : !fir.ref<i32>
1062     omp.terminator
1063   }
1064   return
1067 fir.global common @var_common_(dense<0> : vector<8xi8>) {alignment = 4 : i64} : !fir.array<8xi8>
1069 // -----
1072 func.func @use_string(%arg0 : !fir.ref<!fir.char<1,?>>) {
1073   return
1076 func.func @use_index(%arg0 : index) {
1077   return
1080 // CHECK-LABEL:   llvm.func @alloca_hoisting_openmp() {
1081 // CHECK:           %[[VAL_0:.*]] = llvm.mlir.constant(6 : index) : i64
1082 // CHECK:           %[[VAL_1:.*]] = llvm.mlir.constant(1 : i32) : i32
1083 // CHECK:           %[[VAL_2:.*]] = llvm.mlir.constant(42 : i32) : i32
1084 // CHECK:           omp.parallel {
1085 // CHECK:             %[[VAL_3:.*]] = llvm.mlir.constant(6 : index) : i64
1086 // CHECK:             %[[VAL_4:.*]] = llvm.alloca %[[VAL_3]] x i8 : (i64) -> !llvm.ptr
1087 // CHECK:             omp.wsloop {
1088 // CHECK:               omp.loop_nest (%[[VAL_5:.*]]) : i32 = (%[[VAL_1]]) to (%[[VAL_2]]) inclusive step (%[[VAL_1]]) {
1089 // CHECK:                 %[[VAL_6:.*]] = llvm.mlir.constant(1 : i64) : i64
1090 // CHECK:                 llvm.call @use_string(%[[VAL_4]]) : (!llvm.ptr) -> ()
1091 // CHECK:                 omp.yield
1092 // CHECK:               }
1093 // CHECK:             }
1094 // CHECK:             omp.terminator
1095 // CHECK:           }
1096 // CHECK:           llvm.call @use_index(%[[VAL_0]]) : (i64) -> ()
1097 // CHECK:           llvm.return
1098 // CHECK:         }
1099 func.func @alloca_hoisting_openmp() {
1100   %c6 = arith.constant 6 : index
1101   %c1_i32 = arith.constant 1 : i32
1102   %c42_i32 = arith.constant 42 : i32
1103   omp.parallel {
1104     omp.wsloop {
1105       omp.loop_nest (%arg0) : i32 = (%c1_i32) to (%c42_i32) inclusive step (%c1_i32) {
1106         %0 = fir.alloca !fir.char<1,?>(%c6 : index)
1107         fir.call @use_string(%0) : (!fir.ref<!fir.char<1,?>>) -> ()
1108         omp.yield
1109       }
1110     }
1111     omp.terminator
1112   }
1113   fir.call @use_index(%c6) : (index) -> ()
1114   return
1117 // -----
1119 // NOTE: This test (and the other allocatable member map tests below) uses mock
1120 // bounds to simplify the example, the real bounds generation is more complex
1121 // as it has to access the box information. However, it's not what the test
1122 // aims to check. The test aims to check the parent member bindings and
1123 // acceses are appropriately maintained when lowering to the LLVM dialect.
1125 // CHECK-LABEL:  llvm.func @map_dtype_alloca_mem
1126 // CHECK-SAME:   %[[ARG_0:.*]]: !llvm.ptr)
1127 func.func @map_dtype_alloca_mem(%arg0 : !fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>) {
1128   %c4 = arith.constant 4 : index
1129   %c1 = arith.constant 1 : index
1130   %c0 = arith.constant 0 : index
1131   // CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) {stride_in_bytes = true}
1132   %0 = omp.map.bounds lower_bound(%c0 : index) upper_bound(%c4 : index) extent(%c4 : index) stride(%c1 : index) start_idx(%c0 : index) {stride_in_bytes = true}
1133   // CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ARG_0]][0, 4] : (!llvm.ptr) -> !llvm.ptr, [[STRUCT_TY:!llvm.struct<"_QFRecTy", \(f32, struct<\(ptr, i64, i32, i8, i8, i8, i8\)>, array<10 x i32>, f32, struct<\(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>\)>, i32\)>]]
1134   %1 = fir.coordinate_of %arg0, %c4 : (!fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>, index) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
1135   // CHECK: %[[BADDR_GEP:.*]] = llvm.getelementptr %[[GEP]][0, 0] : (!llvm.ptr) -> !llvm.ptr, [[STRUCT_TY2:!llvm.struct<\(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>\)>]]
1136   %2 = fir.box_offset %1 base_addr : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>
1137   // CHECK: %[[MAP_MEMBER_BADDR:.*]] = omp.map.info var_ptr(%[[GEP]] : !llvm.ptr, i32) var_ptr_ptr(%[[BADDR_GEP]] : !llvm.ptr) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !llvm.ptr
1138   %3 = omp.map.info var_ptr(%1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.array<?xi32>) var_ptr_ptr(%2 : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) bounds(%0) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>
1139   // CHECK: %[[MAP_MEMBER_DESCRIPTOR:.*]] = omp.map.info var_ptr(%[[GEP]] : !llvm.ptr, [[STRUCT_TY2]]) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr
1140   %4 = omp.map.info var_ptr(%1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.box<!fir.heap<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
1141   // CHECK: %[[MAP_PARENT_DTYPE:.*]] = omp.map.info var_ptr(%[[ARG_0]] : !llvm.ptr, [[STRUCT_TY]]) map_clauses(tofrom) capture(ByRef) members(%[[MAP_MEMBER_DESCRIPTOR]], %[[MAP_MEMBER_BADDR]] : [4], [4, 0] : !llvm.ptr, !llvm.ptr) -> !llvm.ptr {partial_map = true}
1142   %5 = omp.map.info var_ptr(%arg0 : !fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>, !fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>) map_clauses(tofrom) capture(ByRef) members(%4, %3 : [4], [4,0] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) -> !fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>> {partial_map = true}
1143   // CHECK: omp.target map_entries(%[[MAP_MEMBER_DESCRIPTOR]] -> %[[ARG_1:.*]], %[[MAP_MEMBER_BADDR]] -> %[[ARG_2:.*]], %[[MAP_PARENT_DTYPE]] -> %[[ARG_3:.*]] : !llvm.ptr, !llvm.ptr, !llvm.ptr) {
1144   omp.target map_entries(%4 -> %arg1, %3 -> %arg2, %5 -> %arg3 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>, !fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>) {
1145     omp.terminator
1146   }
1147   return
1150 // -----
1152 // CHECK-LABEL:  llvm.func @map_dtype_alloca_mem2
1153 // CHECK-SAME:   %[[ARG_0:.*]]: !llvm.ptr)
1154 func.func @map_dtype_alloca_mem2(%arg0 : !fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>>) {
1155   // CHECK: %[[DTYPE_ALLOCATABLE_ALOCA_2:.*]] = llvm.alloca {{.*}} x [[DESC_TY:!llvm.struct<\(ptr, i64, i32, i8, i8, i8, i8, ptr, array<1 x i64>\)>]] {alignment = 8 : i64} : (i32) -> !llvm.ptr
1156   // CHECK: %[[DTYPE_ALLOCATABLE_ALOCA:.*]] = llvm.alloca {{.*}} x [[DESC_TY]] {alignment = 8 : i64} : (i32) -> !llvm.ptr
1157   %c5 = arith.constant 5 : index
1158   %c4 = arith.constant 4 : index
1159   %c1 = arith.constant 1 : index
1160   %c0 = arith.constant 0 : index
1161   // CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) {stride_in_bytes = true}
1162   %0 = omp.map.bounds lower_bound(%c0 : index) upper_bound(%c4 : index) extent(%c4 : index) stride(%c1 : index) start_idx(%c0 : index) {stride_in_bytes = true}
1163   // CHECK: "llvm.intr.memcpy"(%[[DTYPE_ALLOCATABLE_ALOCA]], %[[ARG_0]], {{.*}}) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> ()
1164   %1 = fir.load %arg0 : !fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>>
1165   // CHECK: %[[GEP_DTYPE_BADDR:.*]] = llvm.getelementptr %[[DTYPE_ALLOCATABLE_ALOCA]][0, 0] : (!llvm.ptr) -> !llvm.ptr, [[DESC_TY]]
1166   // CHECK: %[[LOAD_DTYPE_BADDR:.*]] = llvm.load %[[GEP_DTYPE_BADDR]] : !llvm.ptr -> !llvm.ptr
1167   // CHECK: %[[GEP_DTYPE_MEMBER:.*]] = llvm.getelementptr %[[LOAD_DTYPE_BADDR]][0, 4] : (!llvm.ptr) -> !llvm.ptr, [[REC_TY:!llvm.struct<"_QFRecTy", \(f32, struct<\(ptr, i64, i32, i8, i8, i8, i8\)>, array<10 x i32>, f32, struct<\(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>\)>, i32\)>]]
1168   %2 = fir.coordinate_of %1, %c4 : (!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>, index) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
1169   // CHECK: %[[DTYPE_MEMBER_BADDR:.*]] = llvm.getelementptr %[[GEP_DTYPE_MEMBER]][0, 0] : (!llvm.ptr) -> !llvm.ptr, [[DESC_TY2:!llvm.struct<\(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>\)>]]
1170   %3 = fir.box_offset %2 base_addr : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>
1171   // CHECK: %[[MAP_MEMBER_BADDR:.*]] = omp.map.info var_ptr(%[[GEP_DTYPE_MEMBER]] : !llvm.ptr, i32) var_ptr_ptr(%[[DTYPE_MEMBER_BADDR]] : !llvm.ptr) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !llvm.ptr
1172   %4 = omp.map.info var_ptr(%2 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.array<?xi32>) var_ptr_ptr(%3 : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) bounds(%0) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>
1173   // CHECK: %[[MAP_MEMBER_DESC:.*]] = omp.map.info var_ptr(%[[GEP_DTYPE_MEMBER]] : !llvm.ptr, [[DESC_TY2]]) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr
1174   %5 = omp.map.info var_ptr(%2 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.box<!fir.heap<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
1175   // CHECK: "llvm.intr.memcpy"(%[[DTYPE_ALLOCATABLE_ALOCA_2]], %[[ARG_0]], {{.*}}) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> ()
1176   %6 = fir.load %arg0 : !fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>>
1177   // CHECK: %[[GEP_DTYPE_BADDR:.*]] = llvm.getelementptr %[[DTYPE_ALLOCATABLE_ALOCA_2]][0, 0] : (!llvm.ptr) -> !llvm.ptr, [[DESC_TY]]
1178   // CHECK: %[[LOAD_DTYPE_BADDR:.*]] = llvm.load %[[GEP_DTYPE_BADDR]] : !llvm.ptr -> !llvm.ptr
1179   // CHECK: %[[GEP_DTYPE_REGULAR_MEMBER:.*]] = llvm.getelementptr %[[LOAD_DTYPE_BADDR]][0, 5] : (!llvm.ptr) -> !llvm.ptr, [[REC_TY]]
1180   %7 = fir.coordinate_of %6, %c5 : (!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>, index) -> !fir.ref<i32>
1181   // CHECK: %[[MAP_REGULAR_MEMBER:.*]] = omp.map.info var_ptr(%[[GEP_DTYPE_REGULAR_MEMBER]] : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr
1182   %8 = omp.map.info var_ptr(%7 : !fir.ref<i32>, i32) map_clauses(tofrom) capture(ByRef) -> !fir.ref<i32>
1183   // CHECK: %[[GEP_DTYPE_BADDR:.*]] = llvm.getelementptr %[[ARG_0]][0, 0] : (!llvm.ptr) -> !llvm.ptr, [[DESC_TY]]
1184   %9 = fir.box_offset %arg0 base_addr : (!fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>>) -> !fir.llvm_ptr<!fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>
1185   // CHECK: %[[MAP_DTYPE_PARENT_BADDR:.*]] = omp.map.info var_ptr(%[[ARG_0]] : !llvm.ptr, [[REC_TY]]) var_ptr_ptr(%[[GEP_DTYPE_BADDR]] : !llvm.ptr) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr
1186   %10 = omp.map.info var_ptr(%arg0 : !fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>>, !fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>) var_ptr_ptr(%9 : !fir.llvm_ptr<!fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>) map_clauses(tofrom) capture(ByRef) -> !fir.llvm_ptr<!fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>
1187   // CHECK: %[[MAP_DTYPE_PARENT_DESC:.*]] = omp.map.info var_ptr(%[[ARG_0]] : !llvm.ptr, [[DESC_TY]]) map_clauses(tofrom) capture(ByRef) members(%[[MAP_DTYPE_PARENT_BADDR]], %[[MAP_MEMBER_DESC]], %[[MAP_MEMBER_BADDR]], %[[MAP_REGULAR_MEMBER]] : [0], [0, 4], [0, 4, 0], [0, 5] : !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr) -> !llvm.ptr
1188   %11 = omp.map.info var_ptr(%arg0 : !fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>>, !fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>) map_clauses(tofrom) capture(ByRef) members(%10, %5, %4, %8 : [0], [0,4], [0,4,0], [0,5] : !fir.llvm_ptr<!fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>, !fir.ref<i32>) -> !fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>>
1189   // CHECK: omp.target map_entries(%[[MAP_DTYPE_PARENT_BADDR]] -> %[[ARG_1:.*]], %[[MAP_MEMBER_DESC]] -> %[[ARG_2:.*]], %[[MAP_MEMBER_BADDR]] -> %[[ARG_3:.*]], %[[MAP_REGULAR_MEMBER]] -> %[[ARG_4:.*]], %[[MAP_DTYPE_PARENT_DESC]] -> %[[ARG_5:.*]] : !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr) {
1190   omp.target map_entries(%10 -> %arg1, %5 -> %arg2, %4 -> %arg3, %8 -> %arg4, %11 -> %arg5 : !fir.llvm_ptr<!fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>, !fir.ref<i32>, !fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>>>) {
1191    omp.terminator
1192   }
1193   return
1196 // -----
1198 // CHECK-LABEL:  llvm.func @map_nested_dtype_alloca_mem
1199 // CHECK-SAME:   %[[ARG_0:.*]]: !llvm.ptr)
1200 func.func @map_nested_dtype_alloca_mem(%arg0 : !fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>>) {
1201   // CHECK: %[[DTYPE_ALLOCATABLE_ALOCA_2:.*]] = llvm.alloca {{.*}} x [[DESC_TY:!llvm.struct<\(ptr, i64, i32, i8, i8, i8, i8, ptr, array<1 x i64>\)>]] {alignment = 8 : i64} : (i32) -> !llvm.ptr
1202   // CHECK: %[[DTYPE_ALLOCATABLE_ALOCA:.*]] = llvm.alloca {{.*}} x [[DESC_TY]] {alignment = 8 : i64} : (i32) -> !llvm.ptr
1203   %c3 = arith.constant 3 : index
1204   %c4 = arith.constant 4 : index
1205   %c6 = arith.constant 6 : index
1206   %c1 = arith.constant 1 : index
1207   %c2 = arith.constant 2 : index
1208   %c0 = arith.constant 0 : index
1209   // CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) {stride_in_bytes = true}
1210   %0 = omp.map.bounds lower_bound(%c0 : index) upper_bound(%c4 : index) extent(%c4 : index) stride(%c1 : index) start_idx(%c0 : index) {stride_in_bytes = true}
1211   // CHECK: "llvm.intr.memcpy"(%[[DTYPE_ALLOCATABLE_ALOCA]], %[[ARG_0]], {{.*}}) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> ()
1212   %1 = fir.load %arg0 : !fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>>
1213   // CHECK: %[[GEP_DTYPE_BADDR:.*]] = llvm.getelementptr %[[DTYPE_ALLOCATABLE_ALOCA]][0, 0] : (!llvm.ptr) -> !llvm.ptr, [[DESC_TY]]
1214   // CHECK: %[[LOAD_GEP_DTYPE_BADDR:.*]] = llvm.load %[[GEP_DTYPE_BADDR]] : !llvm.ptr -> !llvm.ptr
1215   // CHECK: %[[LOAD_NESTED_DTYPE:.*]] = llvm.getelementptr %[[LOAD_GEP_DTYPE_BADDR]][0, 6] : (!llvm.ptr) -> !llvm.ptr, [[REC_TY:!llvm.struct<"_QFRecTy", \(f32, struct<\(ptr, i64, i32, i8, i8, i8, i8\)>, array<10 x i32>, f32, struct<\(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>\)>, i32, struct<"_QFRecTy2", \(f32, array<10 x i32>, struct<\(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>\)>, i32\)>\)>]]
1216   %2 = fir.coordinate_of %1, %c6 : (!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>, index) -> !fir.ref<!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>
1217   // CHECK: %[[GEP_NESTED_DTYPE_ALLOCATABLE_MEMBER:.*]] = llvm.getelementptr %[[LOAD_NESTED_DTYPE]][0, 2] : (!llvm.ptr) -> !llvm.ptr, [[REC_TY2:!llvm.struct<"_QFRecTy2", \(f32, array<10 x i32>, struct<\(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>\)>, i32\)>]]
1218   %3 = fir.coordinate_of %2, %c2 : (!fir.ref<!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>, index) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
1219   // CHECK: %[[GEP_NESTED_DTYPE_ALLOCATABLE_MEMBER_BADDR:.*]] = llvm.getelementptr %[[GEP_NESTED_DTYPE_ALLOCATABLE_MEMBER]][0, 0] : (!llvm.ptr) -> !llvm.ptr, [[DESC_TY2:!llvm.struct<\(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>\)>]]
1220   %4 = fir.box_offset %3 base_addr : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>
1221   // CHECK: %[[MAP_NESTED_MEMBER_BADDR:.*]] = omp.map.info var_ptr(%[[GEP_NESTED_DTYPE_ALLOCATABLE_MEMBER]] : !llvm.ptr, i32) var_ptr_ptr(%[[GEP_NESTED_DTYPE_ALLOCATABLE_MEMBER_BADDR]] : !llvm.ptr) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !llvm.ptr
1222   %5 = omp.map.info var_ptr(%3 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.array<?xi32>) var_ptr_ptr(%4 : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) bounds(%0) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>
1223   // CHECK: %[[MAP_NESTED_MEMBER_DESC:.*]] = omp.map.info var_ptr(%[[GEP_NESTED_DTYPE_ALLOCATABLE_MEMBER]] : !llvm.ptr, [[DESC_TY2]]) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr
1224   %6 = omp.map.info var_ptr(%3 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.box<!fir.heap<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
1225   // CHECK: "llvm.intr.memcpy"(%[[DTYPE_ALLOCATABLE_ALOCA_2]], %[[ARG_0]], {{.*}}) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> ()
1226   // CHECK: %[[GEP_DTYPE_BADDR:.*]] = llvm.getelementptr %[[DTYPE_ALLOCATABLE_ALOCA_2]][0, 0] : (!llvm.ptr) -> !llvm.ptr, [[DESC_TY]]
1227   // CHECK: %[[LOAD_GEP_DTYPE_BADDR:.*]] = llvm.load %[[GEP_DTYPE_BADDR]] : !llvm.ptr -> !llvm.ptr
1228   %7 = fir.load %arg0 : !fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>>
1229   // CHECK: %[[LOAD_NESTED_DTYPE:.*]] = llvm.getelementptr %[[LOAD_GEP_DTYPE_BADDR]][0, 6] : (!llvm.ptr) -> !llvm.ptr, [[REC_TY]]
1230   %8 = fir.coordinate_of %7, %c6 : (!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>, index) -> !fir.ref<!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>
1231   // CHECK: %[[NESTED_DTYPE_REGULAR_MEMBER_GEP:.*]] = llvm.getelementptr %[[LOAD_NESTED_DTYPE]][0, 3] : (!llvm.ptr) -> !llvm.ptr, [[REC_TY2]]
1232   %9 = fir.coordinate_of %8, %c3 : (!fir.ref<!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>, index) -> !fir.ref<i32>
1233   // CHECK: %[[MAP_REGULAR_NESTED_MEMBER:.*]] = omp.map.info var_ptr(%[[NESTED_DTYPE_REGULAR_MEMBER_GEP]] : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr
1234   %10 = omp.map.info var_ptr(%9 : !fir.ref<i32>, i32) map_clauses(tofrom) capture(ByRef) -> !fir.ref<i32>
1235   // CHECK: %[[DTYPE_BADDR_GEP:.*]] = llvm.getelementptr %[[ARG_0]][0, 0] : (!llvm.ptr) -> !llvm.ptr, [[DESC_TY]]
1236   %11 = fir.box_offset %arg0 base_addr : (!fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>>) -> !fir.llvm_ptr<!fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>
1237   // CHECK: %[[MAP_PARENT_BADDR:.*]] = omp.map.info var_ptr(%[[ARG_0]] : !llvm.ptr, [[REC_TY]]) var_ptr_ptr(%[[DTYPE_BADDR_GEP]] : !llvm.ptr) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr
1238   %12 = omp.map.info var_ptr(%arg0 : !fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>>, !fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>) var_ptr_ptr(%11 : !fir.llvm_ptr<!fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>) map_clauses(tofrom) capture(ByRef) -> !fir.llvm_ptr<!fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>
1239   // CHECK: %[[MAP_PARENT_DESC:.*]] = omp.map.info var_ptr(%[[ARG_0]] : !llvm.ptr, [[DESC_TY]]) map_clauses(tofrom) capture(ByRef) members(%[[MAP_PARENT_BADDR]], %[[MAP_NESTED_MEMBER_DESC]], %[[MAP_NESTED_MEMBER_BADDR]], %[[MAP_REGULAR_NESTED_MEMBER]] : [0], [0, 6, 2], [0, 6, 2, 0], [0, 6, 3] : !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr) -> !llvm.ptr
1240   %13 = omp.map.info var_ptr(%arg0 : !fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>>, !fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>) map_clauses(tofrom) capture(ByRef) members(%12, %6, %5, %10 : [0], [0,6,2], [0,6,2,0], [0,6,3] : !fir.llvm_ptr<!fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>, !fir.ref<i32>) -> !fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>>
1241   // CHECK: omp.target map_entries(%[[MAP_PARENT_BADDR]] -> %[[ARG_1:.*]], %[[MAP_NESTED_MEMBER_DESC]] -> %[[ARG_2:.*]], %[[MAP_NESTED_MEMBER_BADDR]] -> %[[ARG_3:.*]], %[[MAP_REGULAR_NESTED_MEMBER]] -> %[[ARG_4:.*]], %[[MAP_PARENT_DESC]] -> %[[ARG_5:.*]] : !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr, !llvm.ptr) {
1242   omp.target map_entries(%12 -> %arg1, %6 -> %arg2, %5 -> %arg3, %10 -> %arg4, %13 -> %arg5 : !fir.llvm_ptr<!fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>, !fir.ref<i32>, !fir.ref<!fir.box<!fir.heap<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>>>) {
1243     omp.terminator
1244   }
1245   return
1248 // -----
1250 // CHECK-LABEL:  llvm.func @map_nested_dtype_alloca_mem2
1251 // CHECK-SAME:   %[[ARG_0:.*]]: !llvm.ptr)
1252 func.func @map_nested_dtype_alloca_mem2(%arg0 : !fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>) {
1253   %c4 = arith.constant 4 : index
1254   %c1 = arith.constant 1 : index
1255   %c2 = arith.constant 2 : index
1256   %c0 = arith.constant 0 : index
1257   %c6 = arith.constant 6 : index
1258   // CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound({{.*}}) upper_bound({{.*}}) extent({{.*}}) stride({{.*}}) start_idx({{.*}}) {stride_in_bytes = true}
1259   %0 = omp.map.bounds lower_bound(%c0 : index) upper_bound(%c4 : index) extent(%c4 : index) stride(%c1 : index) start_idx(%c0 : index) {stride_in_bytes = true}
1260   // CHECK: %[[NESTED_DTYPE_MEMBER_GEP:.*]] = llvm.getelementptr %[[ARG_0]][0, 6] : (!llvm.ptr) -> !llvm.ptr, [[REC_TY:!llvm.struct<"_QFRecTy", \(f32, struct<\(ptr, i64, i32, i8, i8, i8, i8\)>, array<10 x i32>, f32, struct<\(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>\)>, i32, struct<"_QFRecTy2", \(f32, array<10 x i32>, struct<\(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>\)>, i32\)>\)>]]
1261   %1 = fir.coordinate_of %arg0, %c6 : (!fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>, index) -> !fir.ref<!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>
1262   // CHECK: %[[NESTED_ALLOCATABLE_MEMBER_GEP:.*]] = llvm.getelementptr %[[NESTED_DTYPE_MEMBER_GEP]][0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"_QFRecTy2", (f32, array<10 x i32>, struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>, i32)>
1263   %2 = fir.coordinate_of %1, %c2 : (!fir.ref<!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>>, index) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
1264   // CHECK: %[[NESTED_ALLOCATABLE_MEMBER_BADDR_GEP:.*]] = llvm.getelementptr %[[NESTED_ALLOCATABLE_MEMBER_GEP]][0, 0] : (!llvm.ptr) -> !llvm.ptr, [[DESC_TY2]]
1265   %3 = fir.box_offset %2 base_addr : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>
1266   // CHECK: %[[MAP_NESTED_ALLOCATABLE_MEMBER_BADDR:.*]] = omp.map.info var_ptr(%[[NESTED_ALLOCATABLE_MEMBER_GEP]] : !llvm.ptr, i32) var_ptr_ptr(%[[NESTED_ALLOCATABLE_MEMBER_BADDR_GEP]] : !llvm.ptr) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !llvm.ptr
1267   %4 = omp.map.info var_ptr(%2 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.array<?xi32>) var_ptr_ptr(%3 : !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) bounds(%0) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>
1268   // CHECK: %[[MAP_NESTED_ALLOCATABLE_MEMBER_DESC:.*]] = omp.map.info var_ptr(%[[NESTED_ALLOCATABLE_MEMBER_GEP]] : !llvm.ptr, [[DESC_TY2]]) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr
1269   %5 = omp.map.info var_ptr(%2 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.box<!fir.heap<!fir.array<?xi32>>>) map_clauses(tofrom) capture(ByRef) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
1270   // CHECK: %[[MAP_PARENT:.*]] = omp.map.info var_ptr(%[[ARG_0]] : !llvm.ptr, [[REC_TY]]) map_clauses(tofrom) capture(ByRef) members(%[[MAP_NESTED_ALLOCATABLE_MEMBER_DESC]], %[[MAP_NESTED_ALLOCATABLE_MEMBER_BADDR]] : [6, 2], [6, 2, 0] : !llvm.ptr, !llvm.ptr) -> !llvm.ptr {partial_map = true}
1271   %6 = omp.map.info var_ptr(%arg0 : !fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>, !fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>) map_clauses(tofrom) capture(ByRef) members(%5, %4 : [6,2], [6,2,0] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>) -> !fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>> {partial_map = true}
1272   // CHECK: omp.target map_entries(%[[MAP_NESTED_ALLOCATABLE_MEMBER_DESC]] -> %[[ARG_1:.*]], %[[MAP_NESTED_ALLOCATABLE_MEMBER_BADDR]] -> %[[ARG_2:.*]], %[[MAP_PARENT]] -> %[[ARG_3:.*]] : !llvm.ptr, !llvm.ptr, !llvm.ptr) {
1273   omp.target map_entries(%5 -> %arg1, %4 -> %arg2, %6 -> %arg3 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.llvm_ptr<!fir.ref<!fir.array<?xi32>>>, !fir.ref<!fir.type<_QFRecTy{i:f32,scalar:!fir.box<!fir.heap<i32>>,array_i:!fir.array<10xi32>,j:f32,array_j:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32,nest:!fir.type<_QFRecTy2{i:f32,array_i:!fir.array<10xi32>,array_k:!fir.box<!fir.heap<!fir.array<?xi32>>>,k:i32}>}>>) {
1274     omp.terminator
1275   }
1276   return