xref: /llvm-project/flang/test/Lower/OpenACC/acc-kernels-loop.f90 (revision f3d3ec86d1a40a2c86d743384d272ebcd0a1cbd8)
1! This test checks lowering of OpenACC kernels loop combined directive.
2
3! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s
4
5subroutine acc_kernels_loop
6  integer :: i, j
7
8  integer :: async = 1
9  integer :: wait1 = 1
10  integer :: wait2 = 2
11  integer :: numGangs = 1
12  integer :: numWorkers = 10
13  integer :: vectorLength = 128
14  logical :: ifCondition = .TRUE.
15  integer, parameter :: n = 10
16  real, dimension(n) :: a, b, c
17  real, dimension(n, n) :: d, e
18  real, pointer :: f, g
19  integer :: reduction_i
20  real :: reduction_r
21
22  integer :: gangNum = 8
23  integer :: gangStatic = 8
24  integer :: vectorNum = 128
25  integer, parameter :: tileSize = 2
26
27! CHECK: %[[A:.*]] = fir.alloca !fir.array<10xf32> {{{.*}}uniq_name = "{{.*}}Ea"}
28! CHECK: %[[DECLA:.*]]:2 = hlfir.declare %[[A]]
29! CHECK: %[[B:.*]] = fir.alloca !fir.array<10xf32> {{{.*}}uniq_name = "{{.*}}Eb"}
30! CHECK: %[[DECLB:.*]]:2 = hlfir.declare %[[B]]
31! CHECK: %[[C:.*]] = fir.alloca !fir.array<10xf32> {{{.*}}uniq_name = "{{.*}}Ec"}
32! CHECK: %[[DECLC:.*]]:2 = hlfir.declare %[[C]]
33! CHECK: %[[F:.*]] = fir.alloca !fir.box<!fir.ptr<f32>> {bindc_name = "f", uniq_name = "{{.*}}Ef"}
34! CHECK: %[[DECLF:.*]]:2 = hlfir.declare %[[F]]
35! CHECK: %[[G:.*]] = fir.alloca !fir.box<!fir.ptr<f32>> {bindc_name = "g", uniq_name = "{{.*}}Eg"}
36! CHECK: %[[DECLG:.*]]:2 = hlfir.declare %[[G]]
37! CHECK: %[[IFCONDITION:.*]] = fir.address_of(@{{.*}}ifcondition) : !fir.ref<!fir.logical<4>>
38! CHECK: %[[DECLIFCONDITION:.*]]:2 = hlfir.declare %[[IFCONDITION]]
39
40  !$acc kernels
41  !$acc loop
42  DO i = 1, n
43    a(i) = b(i)
44  END DO
45  !$acc end kernels
46
47! CHECK:      acc.kernels {
48! CHECK:        acc.loop private{{.*}} {
49! CHECK:          acc.yield
50! CHECK-NEXT:   }{{$}}
51! CHECK:        acc.terminator
52! CHECK-NEXT: }{{$}}
53
54  !$acc kernels loop
55  DO i = 1, n
56    a(i) = b(i)
57  END DO
58
59! CHECK:      acc.kernels combined(loop) {
60! CHECK:        acc.loop combined(kernels) private{{.*}} {
61! CHECK:          acc.yield
62! CHECK-NEXT:   }{{$}}
63! CHECK:        acc.terminator
64! CHECK-NEXT: }{{$}}
65
66  !$acc kernels loop async
67  DO i = 1, n
68    a(i) = b(i)
69  END DO
70  !$acc end kernels loop
71
72! CHECK:      acc.kernels {{.*}} {
73! CHECK:        acc.loop {{.*}} {
74! CHECK:          acc.yield
75! CHECK-NEXT:   }{{$}}
76! CHECK:        acc.terminator
77! CHECK-NEXT: } attributes {asyncOnly = [#acc.device_type<none>]}
78
79  !$acc kernels loop async(1)
80  DO i = 1, n
81    a(i) = b(i)
82  END DO
83
84! CHECK:      [[ASYNC1:%.*]] = arith.constant 1 : i32
85! CHECK:      acc.kernels {{.*}} async([[ASYNC1]] : i32) {
86! CHECK:        acc.loop {{.*}} {
87! CHECK:          acc.yield
88! CHECK-NEXT:   }{{$}}
89! CHECK:        acc.terminator
90! CHECK-NEXT: }{{$}}
91
92  !$acc kernels loop async(async)
93  DO i = 1, n
94    a(i) = b(i)
95  END DO
96
97! CHECK:      [[ASYNC2:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
98! CHECK:      acc.kernels {{.*}} async([[ASYNC2]] : i32) {
99! CHECK:        acc.loop {{.*}} {
100! CHECK:          acc.yield
101! CHECK-NEXT:   }{{$}}
102! CHECK:        acc.terminator
103! CHECK-NEXT: }{{$}}
104
105  !$acc kernels loop wait
106  DO i = 1, n
107    a(i) = b(i)
108  END DO
109
110! CHECK:      acc.kernels {{.*}} wait {
111! CHECK:        acc.loop {{.*}} {
112! CHECK:          acc.yield
113! CHECK-NEXT:   }{{$}}
114! CHECK:        acc.terminator
115! CHECK-NEXT: }
116
117  !$acc kernels loop wait(1)
118  DO i = 1, n
119    a(i) = b(i)
120  END DO
121
122! CHECK:      [[WAIT1:%.*]] = arith.constant 1 : i32
123! CHECK:      acc.kernels {{.*}} wait({[[WAIT1]] : i32}) {
124! CHECK:        acc.loop
125! CHECK:          acc.yield
126! CHECK-NEXT:   }{{$}}
127! CHECK:        acc.terminator
128! CHECK-NEXT: }{{$}}
129
130  !$acc kernels loop wait(1, 2)
131  DO i = 1, n
132    a(i) = b(i)
133  END DO
134
135! CHECK:      [[WAIT2:%.*]] = arith.constant 1 : i32
136! CHECK:      [[WAIT3:%.*]] = arith.constant 2 : i32
137! CHECK:      acc.kernels {{.*}} wait({[[WAIT2]] : i32, [[WAIT3]] : i32}) {
138! CHECK:        acc.loop
139! CHECK:          acc.yield
140! CHECK-NEXT:   }{{$}}
141! CHECK:        acc.terminator
142! CHECK-NEXT: }{{$}}
143
144  !$acc kernels loop wait(wait1, wait2)
145  DO i = 1, n
146    a(i) = b(i)
147  END DO
148
149! CHECK:      [[WAIT4:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
150! CHECK:      [[WAIT5:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
151! CHECK:      acc.kernels {{.*}} wait({[[WAIT4]] : i32, [[WAIT5]] : i32}) {
152! CHECK:        acc.loop
153! CHECK:          acc.yield
154! CHECK-NEXT:   }{{$}}
155! CHECK:        acc.terminator
156! CHECK-NEXT: }{{$}}
157
158  !$acc kernels loop num_gangs(1)
159  DO i = 1, n
160    a(i) = b(i)
161  END DO
162
163! CHECK:      [[NUMGANGS1:%.*]] = arith.constant 1 : i32
164! CHECK:      acc.kernels {{.*}} num_gangs({[[NUMGANGS1]] : i32}) {
165! CHECK:        acc.loop
166! CHECK:          acc.yield
167! CHECK-NEXT:   }{{$}}
168! CHECK:        acc.terminator
169! CHECK-NEXT: }{{$}}
170
171  !$acc kernels loop num_gangs(numGangs)
172  DO i = 1, n
173    a(i) = b(i)
174  END DO
175
176! CHECK:      [[NUMGANGS2:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
177! CHECK:      acc.kernels {{.*}} num_gangs({[[NUMGANGS2]] : i32}) {
178! CHECK:        acc.loop
179! CHECK:          acc.yield
180! CHECK-NEXT:   }{{$}}
181! CHECK:        acc.terminator
182! CHECK-NEXT: }{{$}}
183
184  !$acc kernels loop num_workers(10)
185  DO i = 1, n
186    a(i) = b(i)
187  END DO
188
189! CHECK:      [[NUMWORKERS1:%.*]] = arith.constant 10 : i32
190! CHECK:      acc.kernels {{.*}} num_workers([[NUMWORKERS1]] : i32) {
191! CHECK:        acc.loop {{.*}} {
192! CHECK:          acc.yield
193! CHECK-NEXT:   }{{$}}
194! CHECK:        acc.terminator
195! CHECK-NEXT: }{{$}}
196
197  !$acc kernels loop num_workers(numWorkers)
198  DO i = 1, n
199    a(i) = b(i)
200  END DO
201
202! CHECK:      [[NUMWORKERS2:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
203! CHECK:      acc.kernels {{.*}} num_workers([[NUMWORKERS2]] : i32) {
204! CHECK:        acc.loop {{.*}} {
205! CHECK:          acc.yield
206! CHECK-NEXT:   }{{$}}
207! CHECK:        acc.terminator
208! CHECK-NEXT: }{{$}}
209
210  !$acc kernels loop vector_length(128)
211  DO i = 1, n
212    a(i) = b(i)
213  END DO
214
215! CHECK:      [[VECTORLENGTH1:%.*]] = arith.constant 128 : i32
216! CHECK:      acc.kernels {{.*}} vector_length([[VECTORLENGTH1]] : i32) {
217! CHECK:        acc.loop {{.*}} {
218! CHECK:          acc.yield
219! CHECK-NEXT:   }{{$}}
220! CHECK:        acc.terminator
221! CHECK-NEXT: }{{$}}
222
223  !$acc kernels loop vector_length(vectorLength)
224  DO i = 1, n
225    a(i) = b(i)
226  END DO
227
228! CHECK:      [[VECTORLENGTH2:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
229! CHECK:      acc.kernels {{.*}} vector_length([[VECTORLENGTH2]] : i32) {
230! CHECK:        acc.loop {{.*}} {
231! CHECK:          acc.yield
232! CHECK-NEXT:   }{{$}}
233! CHECK:        acc.terminator
234! CHECK-NEXT: }{{$}}
235
236  !$acc kernels loop if(.TRUE.)
237  DO i = 1, n
238    a(i) = b(i)
239  END DO
240
241! CHECK:      [[IF1:%.*]] = arith.constant true
242! CHECK:      acc.kernels {{.*}} if([[IF1]]) {
243! CHECK:        acc.loop {{.*}} {
244! CHECK:          acc.yield
245! CHECK-NEXT:   }{{$}}
246! CHECK:        acc.terminator
247! CHECK-NEXT: }{{$}}
248
249  !$acc kernels loop if(ifCondition)
250  DO i = 1, n
251    a(i) = b(i)
252  END DO
253
254! CHECK:      [[IFCOND:%.*]] = fir.load %{{.*}} : !fir.ref<!fir.logical<4>>
255! CHECK:      [[IF2:%.*]] = fir.convert [[IFCOND]] : (!fir.logical<4>) -> i1
256! CHECK:      acc.kernels {{.*}} if([[IF2]]) {
257! CHECK:        acc.loop {{.*}} {
258! CHECK:          acc.yield
259! CHECK-NEXT:   }{{$}}
260! CHECK:        acc.terminator
261! CHECK-NEXT: }{{$}}
262
263  !$acc kernels loop self(.TRUE.)
264  DO i = 1, n
265    a(i) = b(i)
266  END DO
267
268! CHECK:      [[SELF1:%.*]] = arith.constant true
269! CHECK:      acc.kernels {{.*}} self([[SELF1]]) {
270! CHECK:        acc.loop {{.*}} {
271! CHECK:          acc.yield
272! CHECK-NEXT:   }{{$}}
273! CHECK:        acc.terminator
274! CHECK-NEXT: }{{$}}
275
276  !$acc kernels loop self
277  DO i = 1, n
278    a(i) = b(i)
279  END DO
280
281! CHECK:      acc.kernels {{.*}}{
282! CHECK:        acc.loop {{.*}} {
283! CHECK:          acc.yield
284! CHECK-NEXT:   }{{$}}
285! CHECK:        acc.terminator
286! CHECK-NEXT: } attributes {selfAttr}
287
288  !$acc kernels loop self(ifCondition)
289  DO i = 1, n
290    a(i) = b(i)
291  END DO
292
293
294! CHECK:      %[[SELF2:.*]] = fir.convert %[[DECLIFCONDITION]]#1 : (!fir.ref<!fir.logical<4>>) -> i1
295! CHECK:      acc.kernels {{.*}} self(%[[SELF2]]) {
296! CHECK:        acc.loop {{.*}} {
297! CHECK:          acc.yield
298! CHECK-NEXT:   }{{$}}
299! CHECK:        acc.terminator
300! CHECK-NEXT: }{{$}}
301
302  !$acc kernels loop copy(a, b)
303  DO i = 1, n
304    a(i) = b(i)
305  END DO
306
307
308! CHECK:      %[[COPYIN_A:.*]] = acc.copyin varPtr(%[[DECLA]]#0 : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<10xf32>> {dataClause = #acc<data_clause acc_copy>, name = "a"}
309! CHECK:      %[[COPYIN_B:.*]] = acc.copyin varPtr(%[[DECLB]]#0 : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<10xf32>> {dataClause = #acc<data_clause acc_copy>, name = "b"}
310! CHECK:      acc.kernels {{.*}} dataOperands(%[[COPYIN_A]], %[[COPYIN_B]] : !fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>) {
311! CHECK:        acc.loop {{.*}} {
312! CHECK:          acc.yield
313! CHECK-NEXT:   }{{$}}
314! CHECK:        acc.terminator
315! CHECK-NEXT: }{{$}}
316! CHECK:      acc.copyout accPtr(%[[COPYIN_A]] : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) to varPtr(%[[DECLA]]#0 : !fir.ref<!fir.array<10xf32>>) {dataClause = #acc<data_clause acc_copy>, name = "a"}
317! CHECK:      acc.copyout accPtr(%[[COPYIN_B]] : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) to varPtr(%[[DECLB]]#0 : !fir.ref<!fir.array<10xf32>>) {dataClause = #acc<data_clause acc_copy>, name = "b"}
318
319  !$acc kernels loop copy(a) copy(b)
320  DO i = 1, n
321    a(i) = b(i)
322  END DO
323
324! CHECK:      %[[COPYIN_A:.*]] = acc.copyin varPtr(%[[DECLA]]#0 : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<10xf32>> {dataClause = #acc<data_clause acc_copy>, name = "a"}
325! CHECK:      %[[COPYIN_B:.*]] = acc.copyin varPtr(%[[DECLB]]#0 : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<10xf32>> {dataClause = #acc<data_clause acc_copy>, name = "b"}
326! CHECK:      acc.kernels {{.*}} dataOperands(%[[COPYIN_A]], %[[COPYIN_B]] : !fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>) {
327! CHECK:        acc.loop {{.*}} {
328! CHECK:          acc.yield
329! CHECK-NEXT:   }{{$}}
330! CHECK:        acc.terminator
331! CHECK-NEXT: }{{$}}
332! CHECK:      acc.copyout accPtr(%[[COPYIN_A]] : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) to varPtr(%[[DECLA]]#0 : !fir.ref<!fir.array<10xf32>>) {dataClause = #acc<data_clause acc_copy>, name = "a"}
333! CHECK:      acc.copyout accPtr(%[[COPYIN_B]] : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) to varPtr(%[[DECLB]]#0 : !fir.ref<!fir.array<10xf32>>) {dataClause = #acc<data_clause acc_copy>, name = "b"}
334
335  !$acc kernels loop copyin(a) copyin(readonly: b)
336  DO i = 1, n
337    a(i) = b(i)
338  END DO
339
340! CHECK:      %[[COPYIN_A:.*]] = acc.copyin varPtr(%[[DECLA]]#0 : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<10xf32>> {name = "a"}
341! CHECK:      %[[COPYIN_B:.*]] = acc.copyin varPtr(%[[DECLB]]#0 : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<10xf32>> {dataClause = #acc<data_clause acc_copyin_readonly>, name = "b"}
342! CHECK:      acc.kernels {{.*}} dataOperands(%[[COPYIN_A]], %[[COPYIN_B]] : !fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>) {
343! CHECK:        acc.loop {{.*}} {
344! CHECK:          acc.yield
345! CHECK-NEXT:   }{{$}}
346! CHECK:        acc.terminator
347! CHECK-NEXT: }{{$}}
348! CHECK:      acc.delete accPtr(%[[COPYIN_A]] : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) {dataClause = #acc<data_clause acc_copyin>, name = "a"}
349! CHECK:      acc.delete accPtr(%[[COPYIN_B]] : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) {dataClause = #acc<data_clause acc_copyin_readonly>, name = "b"}
350
351  !$acc kernels loop copyout(a) copyout(zero: b)
352  DO i = 1, n
353    a(i) = b(i)
354  END DO
355
356! CHECK:      %[[CREATE_A:.*]] = acc.create varPtr(%[[DECLA]]#0 : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<10xf32>> {dataClause = #acc<data_clause acc_copyout>, name = "a"}
357! CHECK:      %[[CREATE_B:.*]] = acc.create varPtr(%[[DECLB]]#0 : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<10xf32>> {dataClause = #acc<data_clause acc_copyout>, name = "b"}
358! CHECK:      acc.kernels {{.*}} dataOperands(%[[CREATE_A]], %[[CREATE_B]] : !fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>) {
359! CHECK:        acc.loop {{.*}} {
360! CHECK:          acc.yield
361! CHECK-NEXT:   }{{$}}
362! CHECK:        acc.terminator
363! CHECK-NEXT: }{{$}}
364! CHECK:      acc.copyout accPtr(%[[CREATE_A]] : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) to varPtr(%[[DECLA]]#0 : !fir.ref<!fir.array<10xf32>>) {name = "a"}
365! CHECK:      acc.copyout accPtr(%[[CREATE_B]] : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) to varPtr(%[[DECLB]]#0 : !fir.ref<!fir.array<10xf32>>) {name = "b"}
366
367  !$acc kernels loop create(b) create(zero: a)
368  DO i = 1, n
369    a(i) = b(i)
370  END DO
371
372! CHECK:      %[[CREATE_B:.*]] = acc.create varPtr(%[[DECLB]]#0 : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<10xf32>> {name = "b"}
373! CHECK:      %[[CREATE_A:.*]] = acc.create varPtr(%[[DECLA]]#0 : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<10xf32>> {dataClause = #acc<data_clause acc_create_zero>, name = "a"}
374! CHECK:      acc.kernels {{.*}} dataOperands(%[[CREATE_B]], %[[CREATE_A]] : !fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>) {
375! CHECK:        acc.loop {{.*}} {
376! CHECK:          acc.yield
377! CHECK-NEXT:   }{{$}}
378! CHECK:        acc.terminator
379! CHECK-NEXT: }{{$}}
380! CHECK:      acc.delete accPtr(%[[CREATE_B]] : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) {dataClause = #acc<data_clause acc_create>, name = "b"}
381! CHECK:      acc.delete accPtr(%[[CREATE_A]] : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) {dataClause = #acc<data_clause acc_create_zero>, name = "a"}
382
383  !$acc kernels loop no_create(a, b)
384  DO i = 1, n
385    a(i) = b(i)
386  END DO
387
388! CHECK:      %[[NOCREATE_A:.*]] = acc.nocreate varPtr(%[[DECLA]]#0 : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<10xf32>> {name = "a"}
389! CHECK:      %[[NOCREATE_B:.*]] = acc.nocreate varPtr(%[[DECLB]]#0 : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<10xf32>> {name = "b"}
390! CHECK:      acc.kernels {{.*}} dataOperands(%[[NOCREATE_A]], %[[NOCREATE_B]] : !fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>) {
391! CHECK:        acc.loop {{.*}} {
392! CHECK:          acc.yield
393! CHECK-NEXT:   }{{$}}
394! CHECK:        acc.terminator
395! CHECK-NEXT: }{{$}}
396
397  !$acc kernels loop present(a, b)
398  DO i = 1, n
399    a(i) = b(i)
400  END DO
401
402! CHECK:      %[[PRESENT_A:.*]] = acc.present varPtr(%[[DECLA]]#0 : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<10xf32>> {name = "a"}
403! CHECK:      %[[PRESENT_B:.*]] = acc.present varPtr(%[[DECLB]]#0 : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<10xf32>> {name = "b"}
404! CHECK:      acc.kernels {{.*}} dataOperands(%[[PRESENT_A]], %[[PRESENT_B]] : !fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>) {
405! CHECK:        acc.loop {{.*}} {
406! CHECK:          acc.yield
407! CHECK-NEXT:   }{{$}}
408! CHECK:        acc.terminator
409! CHECK-NEXT: }{{$}}
410
411  !$acc kernels loop deviceptr(a) deviceptr(b)
412  DO i = 1, n
413    a(i) = b(i)
414  END DO
415
416! CHECK:      %[[DEVICEPTR_A:.*]] = acc.deviceptr varPtr(%[[DECLA]]#0 : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<10xf32>> {name = "a"}
417! CHECK:      %[[DEVICEPTR_B:.*]] = acc.deviceptr varPtr(%[[DECLB]]#0 : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<10xf32>> {name = "b"}
418! CHECK:      acc.kernels {{.*}} dataOperands(%[[DEVICEPTR_A]], %[[DEVICEPTR_B]] : !fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>) {
419! CHECK:        acc.loop {{.*}} {
420! CHECK:          acc.yield
421! CHECK-NEXT:   }{{$}}
422! CHECK:        acc.terminator
423! CHECK-NEXT: }{{$}}
424
425  !$acc kernels loop attach(f, g)
426  DO i = 1, n
427    a(i) = b(i)
428  END DO
429
430! CHECK:      %[[BOX_F:.*]] = fir.load %[[DECLF]]#0 : !fir.ref<!fir.box<!fir.ptr<f32>>>
431! CHECK:      %[[BOX_ADDR_F:.*]] = fir.box_addr %[[BOX_F]] : (!fir.box<!fir.ptr<f32>>) -> !fir.ptr<f32>
432! CHECK:      %[[ATTACH_F:.*]] = acc.attach varPtr(%[[BOX_ADDR_F]] : !fir.ptr<f32>) -> !fir.ptr<f32> {name = "f"}
433! CHECK:      %[[BOX_G:.*]] = fir.load %[[DECLG]]#0 : !fir.ref<!fir.box<!fir.ptr<f32>>>
434! CHECK:      %[[BOX_ADDR_G:.*]] = fir.box_addr %[[BOX_G]] : (!fir.box<!fir.ptr<f32>>) -> !fir.ptr<f32>
435! CHECK:      %[[ATTACH_G:.*]] = acc.attach varPtr(%[[BOX_ADDR_G]] : !fir.ptr<f32>) -> !fir.ptr<f32> {name = "g"}
436! CHECK:      acc.kernels {{.*}} dataOperands(%[[ATTACH_F]], %[[ATTACH_G]] : !fir.ptr<f32>, !fir.ptr<f32>) {
437! CHECK:        acc.loop {{.*}} {
438! CHECK:          acc.yield
439! CHECK-NEXT:   }{{$}}
440! CHECK:        acc.terminator
441! CHECK-NEXT: }{{$}}
442
443  !$acc kernels loop seq
444  DO i = 1, n
445    a(i) = b(i)
446  END DO
447
448! CHECK:      acc.kernels {{.*}} {
449! CHECK:        acc.loop {{.*}} {
450! CHECK:          acc.yield
451! CHECK-NEXT:   } attributes {inclusiveUpperbound = array<i1: true>, seq = [#acc.device_type<none>]}
452! CHECK:        acc.terminator
453! CHECK-NEXT: }{{$}}
454
455  !$acc kernels loop auto
456  DO i = 1, n
457    a(i) = b(i)
458  END DO
459
460! CHECK:      acc.kernels {{.*}} {
461! CHECK:        acc.loop {{.*}} {
462! CHECK:          acc.yield
463! CHECK-NEXT:   } attributes {auto_ = [#acc.device_type<none>], inclusiveUpperbound = array<i1: true>}
464! CHECK:        acc.terminator
465! CHECK-NEXT: }{{$}}
466
467  !$acc kernels loop independent
468  DO i = 1, n
469    a(i) = b(i)
470  END DO
471
472! CHECK:      acc.kernels {{.*}} {
473! CHECK:        acc.loop {{.*}} {
474! CHECK:          acc.yield
475! CHECK-NEXT:   } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}
476! CHECK:        acc.terminator
477! CHECK-NEXT: }{{$}}
478
479  !$acc kernels loop gang
480  DO i = 1, n
481    a(i) = b(i)
482  END DO
483
484! CHECK:      acc.kernels {{.*}} {
485! CHECK:        acc.loop {{.*}} gang {{.*}} {
486! CHECK:          acc.yield
487! CHECK-NEXT:   } attributes {inclusiveUpperbound = array<i1: true>}{{$}}
488! CHECK:        acc.terminator
489! CHECK-NEXT: }{{$}}
490
491  !$acc kernels loop gang(num: 8)
492  DO i = 1, n
493    a(i) = b(i)
494  END DO
495
496! CHECK:      acc.kernels {{.*}} {
497! CHECK:        [[GANGNUM1:%.*]] = arith.constant 8 : i32
498! CHECK-NEXT:   acc.loop {{.*}} gang({num=[[GANGNUM1]] : i32}) {{.*}} {
499! CHECK:          acc.yield
500! CHECK-NEXT:   }{{$}}
501! CHECK:        acc.terminator
502! CHECK-NEXT: }{{$}}
503
504  !$acc kernels loop gang(num: gangNum)
505  DO i = 1, n
506    a(i) = b(i)
507  END DO
508
509! CHECK:      acc.kernels {{.*}} {
510! CHECK:        [[GANGNUM2:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
511! CHECK-NEXT:   acc.loop {{.*}} gang({num=[[GANGNUM2]] : i32}) {{.*}} {
512! CHECK:          acc.yield
513! CHECK-NEXT:   }{{$}}
514! CHECK:        acc.terminator
515! CHECK-NEXT: }{{$}}
516
517 !$acc kernels loop gang(num: gangNum, static: gangStatic)
518  DO i = 1, n
519    a(i) = b(i)
520  END DO
521
522! CHECK:      acc.kernels {{.*}} {
523! CHECK:        acc.loop {{.*}} gang({num=%{{.*}} : i32, static=%{{.*}} : i32})
524! CHECK:          acc.yield
525! CHECK-NEXT:   }{{$}}
526! CHECK:        acc.terminator
527! CHECK-NEXT: }{{$}}
528
529  !$acc kernels loop vector
530  DO i = 1, n
531    a(i) = b(i)
532  END DO
533
534! CHECK:      acc.kernels {{.*}} {
535! CHECK:        acc.loop {{.*}} vector {{.*}} {
536! CHECK:          acc.yield
537! CHECK-NEXT:   } attributes {inclusiveUpperbound = array<i1: true>}{{$}}
538! CHECK:        acc.terminator
539! CHECK-NEXT: }{{$}}
540
541  !$acc kernels loop vector(128)
542  DO i = 1, n
543    a(i) = b(i)
544  END DO
545
546! CHECK:      acc.kernels {{.*}} {
547! CHECK:        [[CONSTANT128:%.*]] = arith.constant 128 : i32
548! CHECK:        acc.loop {{.*}} vector([[CONSTANT128]] : i32) {{.*}} {
549! CHECK:          acc.yield
550! CHECK-NEXT:   }{{$}}
551! CHECK:        acc.terminator
552! CHECK-NEXT: }{{$}}
553
554  !$acc kernels loop vector(vectorLength)
555  DO i = 1, n
556    a(i) = b(i)
557  END DO
558
559! CHECK:      acc.kernels {{.*}} {
560! CHECK:        [[VECTORLENGTH:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
561! CHECK:        acc.loop {{.*}} vector([[VECTORLENGTH]] : i32) {{.*}} {
562! CHECK:          acc.yield
563! CHECK-NEXT:   }{{$}}
564! CHECK:        acc.terminator
565! CHECK-NEXT: }{{$}}
566
567  !$acc kernels loop worker
568  DO i = 1, n
569    a(i) = b(i)
570  END DO
571
572! CHECK:      acc.kernels {{.*}} {
573! CHECK:        acc.loop {{.*}} worker {{.*}} {
574! CHECK:          acc.yield
575! CHECK-NEXT:   } attributes {inclusiveUpperbound = array<i1: true>}{{$}}
576! CHECK:        acc.terminator
577! CHECK-NEXT: }{{$}}
578
579  !$acc kernels loop worker(128)
580  DO i = 1, n
581    a(i) = b(i)
582  END DO
583
584! CHECK:      acc.kernels {{.*}} {
585! CHECK:        [[WORKER128:%.*]] = arith.constant 128 : i32
586! CHECK:        acc.loop {{.*}} worker([[WORKER128]] : i32) {{.*}} {
587! CHECK:          acc.yield
588! CHECK-NEXT:   }{{$}}
589! CHECK:        acc.terminator
590! CHECK-NEXT: }{{$}}
591
592  !$acc kernels loop collapse(2)
593  DO i = 1, n
594    DO j = 1, n
595      d(i, j) = e(i, j)
596    END DO
597  END DO
598
599! CHECK:      acc.kernels {{.*}} {
600! CHECK:        acc.loop {{.*}} {
601! CHECK:          acc.yield
602! CHECK-NEXT:   } attributes {collapse = [2], collapseDeviceType = [#acc.device_type<none>], inclusiveUpperbound = array<i1: true, true>}
603! CHECK:        acc.terminator
604! CHECK-NEXT: }{{$}}
605
606  !$acc kernels loop
607  DO i = 1, n
608    !$acc loop
609    DO j = 1, n
610      d(i, j) = e(i, j)
611    END DO
612  END DO
613
614! CHECK:      acc.kernels {{.*}} {
615! CHECK:        acc.loop {{.*}} {
616! CHECK:            acc.loop {{.*}} {
617! CHECK:              acc.yield
618! CHECK-NEXT:     }{{$}}
619! CHECK:          acc.yield
620! CHECK-NEXT:   }{{$}}
621! CHECK:        acc.terminator
622! CHECK-NEXT: }{{$}}
623
624 !$acc kernels loop tile(2)
625  DO i = 1, n
626    a(i) = b(i)
627  END DO
628
629! CHECK:      acc.kernels {{.*}} {
630! CHECK:        [[TILESIZE:%.*]] = arith.constant 2 : i32
631! CHECK:        acc.loop {{.*}} tile({[[TILESIZE]] : i32}) {{.*}} {
632! CHECK:          acc.yield
633! CHECK-NEXT:   }{{$}}
634! CHECK:        acc.terminator
635! CHECK-NEXT: }{{$}}
636
637 !$acc kernels loop tile(*)
638  DO i = 1, n
639    a(i) = b(i)
640  END DO
641
642! CHECK:      acc.kernels {{.*}} {
643! CHECK:        [[TILESIZEM1:%.*]] = arith.constant -1 : i32
644! CHECK:        acc.loop {{.*}} tile({[[TILESIZEM1]] : i32}) {{.*}} {
645! CHECK:          acc.yield
646! CHECK-NEXT:   }{{$}}
647! CHECK:        acc.terminator
648! CHECK-NEXT: }{{$}}
649
650  !$acc kernels loop tile(2, 2)
651  DO i = 1, n
652    DO j = 1, n
653      d(i, j) = e(i, j)
654    END DO
655  END DO
656
657! CHECK:      acc.kernels {{.*}} {
658! CHECK:        [[TILESIZE1:%.*]] = arith.constant 2 : i32
659! CHECK:        [[TILESIZE2:%.*]] = arith.constant 2 : i32
660! CHECK:        acc.loop {{.*}} tile({[[TILESIZE1]] : i32, [[TILESIZE2]] : i32}) {{.*}} {
661! CHECK:          acc.yield
662! CHECK-NEXT:   }{{$}}
663! CHECK:        acc.terminator
664! CHECK-NEXT: }{{$}}
665
666  !$acc kernels loop tile(tileSize)
667  DO i = 1, n
668    a(i) = b(i)
669  END DO
670
671! CHECK:      acc.kernels {{.*}} {
672! CHECK:        acc.loop {{.*}} tile({%{{.*}} : i32}) {{.*}} {
673! CHECK:          acc.yield
674! CHECK-NEXT:   }{{$}}
675! CHECK:        acc.terminator
676! CHECK-NEXT: }{{$}}
677
678  !$acc kernels loop tile(tileSize, tileSize)
679  DO i = 1, n
680    DO j = 1, n
681      d(i, j) = e(i, j)
682    END DO
683  END DO
684
685! CHECK:      acc.kernels {{.*}} {
686! CHECK:        acc.loop {{.*}} tile({%{{.*}} : i32, %{{.*}} : i32}) {{.*}} {
687! CHECK:          acc.yield
688! CHECK-NEXT:   }{{$}}
689! CHECK:        acc.terminator
690! CHECK-NEXT: }{{$}}
691
692  !$acc kernels loop reduction(+:reduction_r) reduction(*:reduction_i)
693  do i = 1, n
694    reduction_r = reduction_r + a(i)
695    reduction_i = 1
696  end do
697
698! CHECK:      %[[COPYINREDR:.*]] = acc.copyin varPtr(%{{.*}} : !fir.ref<f32>) -> !fir.ref<f32> {dataClause = #acc<data_clause acc_reduction>, implicit = true, name = "reduction_r"}
699! CHECK:      %[[COPYINREDI:.*]] = acc.copyin varPtr(%{{.*}} : !fir.ref<i32>) -> !fir.ref<i32> {dataClause = #acc<data_clause acc_reduction>, implicit = true, name = "reduction_i"}
700! CHECK:      acc.kernels {{.*}} dataOperands(%[[COPYINREDR]], %[[COPYINREDI]] : !fir.ref<f32>, !fir.ref<i32>) {
701! CHECK:        acc.loop {{.*}} reduction(@reduction_add_ref_f32 -> %{{.*}} : !fir.ref<f32>, @reduction_mul_ref_i32 -> %{{.*}} : !fir.ref<i32>) {{.*}} {
702! CHECK:          acc.yield
703! CHECK-NEXT:   }{{$}}
704! CHECK:        acc.terminator
705! CHECK-NEXT: }{{$}}
706! CHECK:      acc.copyout accPtr(%[[COPYINREDR]] : !fir.ref<f32>) to varPtr(%{{.*}} : !fir.ref<f32>) {dataClause = #acc<data_clause acc_reduction>, implicit = true, name = "reduction_r"}
707! CHECK:      acc.copyout accPtr(%[[COPYINREDI]] : !fir.ref<i32>) to varPtr(%{{.*}} : !fir.ref<i32>) {dataClause = #acc<data_clause acc_reduction>, implicit = true, name = "reduction_i"}
708
709end subroutine
710