xref: /llvm-project/flang/test/Lower/OpenACC/acc-parallel-loop.f90 (revision f3d3ec86d1a40a2c86d743384d272ebcd0a1cbd8)
1! This test checks lowering of OpenACC parallel loop combined directive.
2
3! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s
4
5! CHECK-LABEL: func.func @_QPacc_parallel_loop()
6
7subroutine acc_parallel_loop
8  integer :: i, j
9
10  integer :: async = 1
11  integer :: wait1 = 1
12  integer :: wait2 = 2
13  integer :: numGangs = 1
14  integer :: numWorkers = 10
15  integer :: vectorLength = 128
16  logical :: ifCondition = .TRUE.
17  integer, parameter :: n = 10
18  real, dimension(n) :: a, b, c
19  real, dimension(n, n) :: d, e
20  real, pointer :: f, g
21  integer :: reduction_i
22  real :: reduction_r
23
24  integer :: gangNum = 8
25  integer :: gangStatic = 8
26  integer :: vectorNum = 128
27  integer, parameter :: tileSize = 2
28
29! CHECK: %[[A:.*]] = fir.alloca !fir.array<10xf32> {{{.*}}uniq_name = "{{.*}}Ea"}
30! CHECK: %[[DECLA:.*]]:2 = hlfir.declare %[[A]]
31! CHECK: %[[B:.*]] = fir.alloca !fir.array<10xf32> {{{.*}}uniq_name = "{{.*}}Eb"}
32! CHECK: %[[DECLB:.*]]:2 = hlfir.declare %[[B]]
33! CHECK: %[[C:.*]] = fir.alloca !fir.array<10xf32> {{{.*}}uniq_name = "{{.*}}Ec"}
34! CHECK: %[[DECLC:.*]]:2 = hlfir.declare %[[C]]
35! CHECK: %[[F:.*]] = fir.alloca !fir.box<!fir.ptr<f32>> {bindc_name = "f", uniq_name = "{{.*}}Ef"}
36! CHECK: %[[DECLF:.*]]:2 = hlfir.declare %[[F]]
37! CHECK: %[[G:.*]] = fir.alloca !fir.box<!fir.ptr<f32>> {bindc_name = "g", uniq_name = "{{.*}}Eg"}
38! CHECK: %[[DECLG:.*]]:2 = hlfir.declare %[[G]]
39! CHECK: %[[IFCONDITION:.*]] = fir.address_of(@{{.*}}ifcondition) : !fir.ref<!fir.logical<4>>
40! CHECK: %[[DECLIFCONDITION:.*]]:2 = hlfir.declare %[[IFCONDITION]]
41
42  !$acc parallel
43  !$acc loop
44  DO i = 1, n
45    a(i) = b(i)
46  END DO
47  !$acc end parallel
48
49! CHECK:      acc.parallel {
50! CHECK:        acc.loop private{{.*}} {
51! CHECK:          acc.yield
52! CHECK-NEXT:   }{{$}}
53! CHECK:        acc.yield
54! CHECK-NEXT: }{{$}}
55
56  !$acc parallel loop
57  DO i = 1, n
58    a(i) = b(i)
59  END DO
60
61! CHECK:      acc.parallel combined(loop) {
62! CHECK:        acc.loop combined(parallel) private{{.*}} {
63! CHECK:          acc.yield
64! CHECK-NEXT:   }{{$}}
65! CHECK:        acc.yield
66! CHECK-NEXT: }{{$}}
67
68  !$acc parallel loop async
69  DO i = 1, n
70    a(i) = b(i)
71  END DO
72  !$acc end parallel loop
73
74! CHECK:      acc.parallel {{.*}} {
75! CHECK:        acc.loop {{.*}} {
76! CHECK:          acc.yield
77! CHECK-NEXT:   }{{$}}
78! CHECK:        acc.yield
79! CHECK-NEXT: } attributes {asyncOnly = [#acc.device_type<none>]}
80
81  !$acc parallel loop async(1)
82  DO i = 1, n
83    a(i) = b(i)
84  END DO
85
86! CHECK:      [[ASYNC1:%.*]] = arith.constant 1 : i32
87! CHECK:      acc.parallel {{.*}} async([[ASYNC1]] : i32) {
88! CHECK:        acc.loop {{.*}} {
89! CHECK:          acc.yield
90! CHECK-NEXT:   }{{$}}
91! CHECK:        acc.yield
92! CHECK-NEXT: }{{$}}
93
94  !$acc parallel loop async(async)
95  DO i = 1, n
96    a(i) = b(i)
97  END DO
98
99! CHECK:      [[ASYNC2:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
100! CHECK:      acc.parallel {{.*}} async([[ASYNC2]] : i32) {
101! CHECK:        acc.loop {{.*}} {
102! CHECK:          acc.yield
103! CHECK-NEXT:   }{{$}}
104! CHECK:        acc.yield
105! CHECK-NEXT: }{{$}}
106
107  !$acc parallel loop wait
108  DO i = 1, n
109    a(i) = b(i)
110  END DO
111
112! CHECK:      acc.parallel {{.*}} wait {
113! CHECK:        acc.loop {{.*}} {
114! CHECK:          acc.yield
115! CHECK-NEXT:   }{{$}}
116! CHECK:        acc.yield
117! CHECK-NEXT: }
118
119  !$acc parallel loop wait(1)
120  DO i = 1, n
121    a(i) = b(i)
122  END DO
123
124! CHECK:      [[WAIT1:%.*]] = arith.constant 1 : i32
125! CHECK:      acc.parallel {{.*}} wait({[[WAIT1]] : i32}) {
126! CHECK:        acc.loop
127! CHECK:          acc.yield
128! CHECK-NEXT:   }{{$}}
129! CHECK:        acc.yield
130! CHECK-NEXT: }{{$}}
131
132  !$acc parallel loop wait(1, 2)
133  DO i = 1, n
134    a(i) = b(i)
135  END DO
136
137! CHECK:      [[WAIT2:%.*]] = arith.constant 1 : i32
138! CHECK:      [[WAIT3:%.*]] = arith.constant 2 : i32
139! CHECK:      acc.parallel {{.*}} wait({[[WAIT2]] : i32, [[WAIT3]] : i32}) {
140! CHECK:        acc.loop
141! CHECK:          acc.yield
142! CHECK-NEXT:   }{{$}}
143! CHECK:        acc.yield
144! CHECK-NEXT: }{{$}}
145
146  !$acc parallel loop wait(wait1, wait2)
147  DO i = 1, n
148    a(i) = b(i)
149  END DO
150
151! CHECK:      [[WAIT4:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
152! CHECK:      [[WAIT5:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
153! CHECK:      acc.parallel {{.*}} wait({[[WAIT4]] : i32, [[WAIT5]] : i32}) {
154! CHECK:        acc.loop
155! CHECK:          acc.yield
156! CHECK-NEXT:   }{{$}}
157! CHECK:        acc.yield
158! CHECK-NEXT: }{{$}}
159
160  !$acc parallel loop num_gangs(1)
161  DO i = 1, n
162    a(i) = b(i)
163  END DO
164
165! CHECK:      [[NUMGANGS1:%.*]] = arith.constant 1 : i32
166! CHECK:      acc.parallel {{.*}} num_gangs({[[NUMGANGS1]] : i32}) {
167! CHECK:        acc.loop
168! CHECK:          acc.yield
169! CHECK-NEXT:   }{{$}}
170! CHECK:        acc.yield
171! CHECK-NEXT: }{{$}}
172
173  !$acc parallel loop num_gangs(numGangs)
174  DO i = 1, n
175    a(i) = b(i)
176  END DO
177
178! CHECK:      [[NUMGANGS2:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
179! CHECK:      acc.parallel {{.*}} num_gangs({[[NUMGANGS2]] : i32}) {
180! CHECK:        acc.loop
181! CHECK:          acc.yield
182! CHECK-NEXT:   }{{$}}
183! CHECK:        acc.yield
184! CHECK-NEXT: }{{$}}
185
186  !$acc parallel loop num_workers(10)
187  DO i = 1, n
188    a(i) = b(i)
189  END DO
190
191! CHECK:      [[NUMWORKERS1:%.*]] = arith.constant 10 : i32
192! CHECK:      acc.parallel {{.*}} num_workers([[NUMWORKERS1]] : i32) {
193! CHECK:        acc.loop {{.*}} {
194! CHECK:          acc.yield
195! CHECK-NEXT:   }{{$}}
196! CHECK:        acc.yield
197! CHECK-NEXT: }{{$}}
198
199  !$acc parallel loop num_workers(numWorkers)
200  DO i = 1, n
201    a(i) = b(i)
202  END DO
203
204! CHECK:      [[NUMWORKERS2:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
205! CHECK:      acc.parallel {{.*}} num_workers([[NUMWORKERS2]] : i32) {
206! CHECK:        acc.loop {{.*}} {
207! CHECK:          acc.yield
208! CHECK-NEXT:   }{{$}}
209! CHECK:        acc.yield
210! CHECK-NEXT: }{{$}}
211
212  !$acc parallel loop vector_length(128)
213  DO i = 1, n
214    a(i) = b(i)
215  END DO
216
217! CHECK:      [[VECTORLENGTH1:%.*]] = arith.constant 128 : i32
218! CHECK:      acc.parallel {{.*}} vector_length([[VECTORLENGTH1]] : i32) {
219! CHECK:        acc.loop {{.*}} {
220! CHECK:          acc.yield
221! CHECK-NEXT:   }{{$}}
222! CHECK:        acc.yield
223! CHECK-NEXT: }{{$}}
224
225  !$acc parallel loop vector_length(vectorLength)
226  DO i = 1, n
227    a(i) = b(i)
228  END DO
229
230! CHECK:      [[VECTORLENGTH2:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
231! CHECK:      acc.parallel {{.*}} vector_length([[VECTORLENGTH2]] : i32) {
232! CHECK:        acc.loop {{.*}} {
233! CHECK:          acc.yield
234! CHECK-NEXT:   }{{$}}
235! CHECK:        acc.yield
236! CHECK-NEXT: }{{$}}
237
238  !$acc parallel loop if(.TRUE.)
239  DO i = 1, n
240    a(i) = b(i)
241  END DO
242
243! CHECK:      [[IF1:%.*]] = arith.constant true
244! CHECK:      acc.parallel {{.*}} if([[IF1]]) {
245! CHECK:        acc.loop {{.*}} {
246! CHECK:          acc.yield
247! CHECK-NEXT:   }{{$}}
248! CHECK:        acc.yield
249! CHECK-NEXT: }{{$}}
250
251  !$acc parallel loop if(ifCondition)
252  DO i = 1, n
253    a(i) = b(i)
254  END DO
255
256! CHECK:      [[IFCOND:%.*]] = fir.load %{{.*}} : !fir.ref<!fir.logical<4>>
257! CHECK:      [[IF2:%.*]] = fir.convert [[IFCOND]] : (!fir.logical<4>) -> i1
258! CHECK:      acc.parallel {{.*}} if([[IF2]]) {
259! CHECK:        acc.loop {{.*}} {
260! CHECK:          acc.yield
261! CHECK-NEXT:   }{{$}}
262! CHECK:        acc.yield
263! CHECK-NEXT: }{{$}}
264
265  !$acc parallel loop self(.TRUE.)
266  DO i = 1, n
267    a(i) = b(i)
268  END DO
269
270! CHECK:      [[SELF1:%.*]] = arith.constant true
271! CHECK:      acc.parallel {{.*}} self([[SELF1]]) {
272! CHECK:        acc.loop {{.*}} {
273! CHECK:          acc.yield
274! CHECK-NEXT:   }{{$}}
275! CHECK:        acc.yield
276! CHECK-NEXT: }{{$}}
277
278  !$acc parallel loop self
279  DO i = 1, n
280    a(i) = b(i)
281  END DO
282
283! CHECK:      acc.parallel {{.*}} {
284! CHECK:        acc.loop {{.*}} {
285! CHECK:          acc.yield
286! CHECK-NEXT:   }{{$}}
287! CHECK:        acc.yield
288! CHECK-NEXT: } attributes {selfAttr}
289
290  !$acc parallel loop self(ifCondition)
291  DO i = 1, n
292    a(i) = b(i)
293  END DO
294
295! CHECK:      %[[SELF2:.*]] = fir.convert %[[DECLIFCONDITION]]#1 : (!fir.ref<!fir.logical<4>>) -> i1
296! CHECK:      acc.parallel {{.*}} self(%[[SELF2]]) {
297! CHECK:        acc.loop {{.*}} {
298! CHECK:          acc.yield
299! CHECK-NEXT:   }{{$}}
300! CHECK:        acc.yield
301! CHECK-NEXT: }{{$}}
302
303  !$acc parallel loop copy(a, b)
304  DO i = 1, n
305    a(i) = b(i)
306  END DO
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.parallel {{.*}} 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.yield
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 parallel 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.parallel {{.*}} 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.yield
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 parallel 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.parallel {{.*}} 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.yield
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 parallel 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.parallel {{.*}} 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.yield
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 parallel 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.parallel {{.*}} 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.yield
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 parallel 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.parallel {{.*}} 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.yield
395! CHECK-NEXT: }{{$}}
396
397  !$acc parallel 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.parallel {{.*}} 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.yield
409! CHECK-NEXT: }{{$}}
410
411  !$acc parallel 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.parallel {{.*}} 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.yield
423! CHECK-NEXT: }{{$}}
424
425  !$acc parallel 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.parallel {{.*}} 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.yield
441! CHECK-NEXT: }{{$}}
442
443  !$acc parallel loop private(a) firstprivate(b)
444  DO i = 1, n
445    a(i) = b(i)
446  END DO
447
448! CHECK:      %[[ACC_PRIVATE_B:.*]] = acc.firstprivate varPtr(%[[DECLB]]#0 : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<10xf32>> {name = "b"}
449! CHECK:      acc.parallel {{.*}} firstprivate(@firstprivatization_section_ext10_ref_10xf32 -> %[[ACC_PRIVATE_B]] : !fir.ref<!fir.array<10xf32>>) {
450! CHECK:      %[[ACC_PRIVATE_A:.*]] = acc.private varPtr(%[[DECLA]]#0 : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<10xf32>> {name = "a"}
451! CHECK:        acc.loop {{.*}} private({{.*}}@privatization_ref_10xf32 -> %[[ACC_PRIVATE_A]] : !fir.ref<!fir.array<10xf32>>)
452! CHECK-NOT:      fir.do_loop
453! CHECK:          acc.yield
454! CHECK-NEXT:   }{{$}}
455! CHECK:        acc.yield
456! CHECK-NEXT: }{{$}}
457
458  !$acc parallel loop seq
459  DO i = 1, n
460    a(i) = b(i)
461  END DO
462
463! CHECK:      acc.parallel {{.*}} {
464! CHECK:        acc.loop {{.*}} {
465! CHECK:          acc.yield
466! CHECK-NEXT:   } attributes {inclusiveUpperbound = array<i1: true>, seq = [#acc.device_type<none>]}
467! CHECK:        acc.yield
468! CHECK-NEXT: }{{$}}
469
470  !$acc parallel loop auto
471  DO i = 1, n
472    a(i) = b(i)
473  END DO
474
475! CHECK:      acc.parallel {{.*}} {
476! CHECK:        acc.loop {{.*}} {
477! CHECK:          acc.yield
478! CHECK-NEXT:   } attributes {auto_ = [#acc.device_type<none>], inclusiveUpperbound = array<i1: true>}
479! CHECK:        acc.yield
480! CHECK-NEXT: }{{$}}
481
482  !$acc parallel loop independent
483  DO i = 1, n
484    a(i) = b(i)
485  END DO
486
487! CHECK:      acc.parallel {{.*}} {
488! CHECK:        acc.loop {{.*}} {
489! CHECK:          acc.yield
490! CHECK-NEXT:   } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}
491! CHECK:        acc.yield
492! CHECK-NEXT: }{{$}}
493
494  !$acc parallel loop gang
495  DO i = 1, n
496    a(i) = b(i)
497  END DO
498
499! CHECK:      acc.parallel {{.*}} {
500! CHECK:        acc.loop {{.*}} gang
501! CHECK:          acc.yield
502! CHECK-NEXT:   } attributes {inclusiveUpperbound = array<i1: true>}{{$}}
503! CHECK:        acc.yield
504! CHECK-NEXT: }{{$}}
505
506  !$acc parallel loop gang(num: 8)
507  DO i = 1, n
508    a(i) = b(i)
509  END DO
510
511! CHECK:      acc.parallel {{.*}} {
512! CHECK:        [[GANGNUM1:%.*]] = arith.constant 8 : i32
513! CHECK-NEXT:   acc.loop {{.*}} gang({num=[[GANGNUM1]] : i32})
514! CHECK:          acc.yield
515! CHECK-NEXT:   }{{$}}
516! CHECK:        acc.yield
517! CHECK-NEXT: }{{$}}
518
519  !$acc parallel loop gang(num: gangNum)
520  DO i = 1, n
521    a(i) = b(i)
522  END DO
523
524! CHECK:      acc.parallel {{.*}} {
525! CHECK:        [[GANGNUM2:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
526! CHECK-NEXT:   acc.loop {{.*}} gang({num=[[GANGNUM2]] : i32})
527! CHECK:          acc.yield
528! CHECK-NEXT:   }{{$}}
529! CHECK:        acc.yield
530! CHECK-NEXT: }{{$}}
531
532 !$acc parallel loop gang(num: gangNum, static: gangStatic)
533  DO i = 1, n
534    a(i) = b(i)
535  END DO
536
537! CHECK:      acc.parallel {{.*}} {
538! CHECK:        acc.loop {{.*}} gang({num=%{{.*}} : i32, static=%{{.*}} : i32})
539! CHECK:          acc.yield
540! CHECK-NEXT:   }{{$}}
541! CHECK:        acc.yield
542! CHECK-NEXT: }{{$}}
543
544  !$acc parallel loop vector
545  DO i = 1, n
546    a(i) = b(i)
547  END DO
548
549! CHECK:      acc.parallel {{.*}} {
550! CHECK:        acc.loop {{.*}} vector
551! CHECK:          acc.yield
552! CHECK-NEXT:   } attributes {inclusiveUpperbound = array<i1: true>}{{$}}
553! CHECK:        acc.yield
554! CHECK-NEXT: }{{$}}
555
556  !$acc parallel loop vector(128)
557  DO i = 1, n
558    a(i) = b(i)
559  END DO
560
561! CHECK:      acc.parallel {{.*}} {
562! CHECK:        [[CONSTANT128:%.*]] = arith.constant 128 : i32
563! CHECK:        acc.loop {{.*}} vector([[CONSTANT128]] : i32) {{.*}} {
564! CHECK:          acc.yield
565! CHECK-NEXT:   }{{$}}
566! CHECK:        acc.yield
567! CHECK-NEXT: }{{$}}
568
569  !$acc parallel loop vector(vectorLength)
570  DO i = 1, n
571    a(i) = b(i)
572  END DO
573
574! CHECK:      acc.parallel {{.*}} {
575! CHECK:        [[VECTORLENGTH:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
576! CHECK:        acc.loop {{.*}} vector([[VECTORLENGTH]] : i32) {{.*}} {
577! CHECK-NOT:      fir.do_loop
578! CHECK:          acc.yield
579! CHECK-NEXT:   }{{$}}
580! CHECK:        acc.yield
581! CHECK-NEXT: }{{$}}
582
583  !$acc parallel loop worker
584  DO i = 1, n
585    a(i) = b(i)
586  END DO
587
588! CHECK:      acc.parallel {{.*}} {
589! CHECK:        acc.loop {{.*}} worker {{.*}} {
590! CHECK-NOT:      fir.do_loop
591! CHECK:          acc.yield
592! CHECK-NEXT:   } attributes {inclusiveUpperbound = array<i1: true>}{{$}}
593! CHECK:        acc.yield
594! CHECK-NEXT: }{{$}}
595
596  !$acc parallel loop worker(128)
597  DO i = 1, n
598    a(i) = b(i)
599  END DO
600
601! CHECK:      acc.parallel {{.*}}{
602! CHECK:        [[WORKER128:%.*]] = arith.constant 128 : i32
603! CHECK:        acc.loop {{.*}} worker([[WORKER128]] : i32) {{.*}} {
604! CHECK-NOT:      fir.do_loop
605! CHECK:          acc.yield
606! CHECK-NEXT:   }{{$}}
607! CHECK:        acc.yield
608! CHECK-NEXT: }{{$}}
609
610  !$acc parallel loop collapse(2)
611  DO i = 1, n
612    DO j = 1, n
613      d(i, j) = e(i, j)
614    END DO
615  END DO
616
617! CHECK:      acc.parallel {{.*}} {
618! CHECK:        acc.loop {{.*}} {
619! CHECK:          acc.yield
620! CHECK-NEXT:   } attributes {collapse = [2], collapseDeviceType = [#acc.device_type<none>], inclusiveUpperbound = array<i1: true, true>}
621! CHECK:        acc.yield
622! CHECK-NEXT: }{{$}}
623
624  !$acc parallel loop
625  DO i = 1, n
626    !$acc loop
627    DO j = 1, n
628      d(i, j) = e(i, j)
629    END DO
630  END DO
631
632! CHECK:      acc.parallel {{.*}} {
633! CHECK:        acc.loop {{.*}} {
634! CHECK:            acc.loop {{.*}} {
635! CHECK:              acc.yield
636! CHECK-NEXT:     }{{$}}
637! CHECK:          acc.yield
638! CHECK-NEXT:   }{{$}}
639! CHECK:        acc.yield
640! CHECK-NEXT: }{{$}}
641
642 !$acc parallel loop tile(2)
643  DO i = 1, n
644    a(i) = b(i)
645  END DO
646
647! CHECK:      acc.parallel {{.*}} {
648! CHECK:        [[TILESIZE:%.*]] = arith.constant 2 : i32
649! CHECK:        acc.loop {{.*}} tile({[[TILESIZE]] : i32}) {{.*}} {
650! CHECK:          acc.yield
651! CHECK-NEXT:   }{{$}}
652! CHECK:        acc.yield
653! CHECK-NEXT: }{{$}}
654
655 !$acc parallel loop tile(*)
656  DO i = 1, n
657    a(i) = b(i)
658  END DO
659
660! CHECK:      acc.parallel {{.*}} {
661! CHECK:        [[TILESIZEM1:%.*]] = arith.constant -1 : i32
662! CHECK:        acc.loop {{.*}} tile({[[TILESIZEM1]] : i32}) {{.*}} {
663! CHECK:          acc.yield
664! CHECK-NEXT:   }{{$}}
665! CHECK:        acc.yield
666! CHECK-NEXT: }{{$}}
667
668  !$acc parallel loop tile(2, 2)
669  DO i = 1, n
670    DO j = 1, n
671      d(i, j) = e(i, j)
672    END DO
673  END DO
674
675! CHECK:      acc.parallel {{.*}} {
676! CHECK:        [[TILESIZE1:%.*]] = arith.constant 2 : i32
677! CHECK:        [[TILESIZE2:%.*]] = arith.constant 2 : i32
678! CHECK:        acc.loop {{.*}} tile({[[TILESIZE1]] : i32, [[TILESIZE2]] : i32}) {{.*}} {
679! CHECK:          acc.yield
680! CHECK-NEXT:   }{{$}}
681! CHECK:        acc.yield
682! CHECK-NEXT: }{{$}}
683
684  !$acc parallel loop tile(tileSize)
685  DO i = 1, n
686    a(i) = b(i)
687  END DO
688
689! CHECK:      acc.parallel {{.*}} {
690! CHECK:        acc.loop {{.*}} tile({%{{.*}} : i32}) {{.*}} {
691! CHECK:          acc.yield
692! CHECK-NEXT:   }{{$}}
693! CHECK:        acc.yield
694! CHECK-NEXT: }{{$}}
695
696  !$acc parallel loop tile(tileSize, tileSize)
697  DO i = 1, n
698    DO j = 1, n
699      d(i, j) = e(i, j)
700    END DO
701  END DO
702
703! CHECK:      acc.parallel {{.*}} {
704! CHECK:        acc.loop {{.*}} tile({%{{.*}} : i32, %{{.*}} : i32}) {{.*}} {
705! CHECK:          acc.yield
706! CHECK-NEXT:   }{{$}}
707! CHECK:        acc.yield
708! CHECK-NEXT: }{{$}}
709
710  !$acc parallel loop reduction(+:reduction_r) reduction(*:reduction_i)
711  do i = 1, n
712    reduction_r = reduction_r + a(i)
713    reduction_i = 1
714  end do
715
716! CHECK:      %[[COPYINREDR:.*]] = acc.copyin varPtr(%{{.*}} : !fir.ref<f32>) -> !fir.ref<f32> {dataClause = #acc<data_clause acc_reduction>, implicit = true, name = "reduction_r"}
717! CHECK:      %[[COPYINREDI:.*]] = acc.copyin varPtr(%{{.*}} : !fir.ref<i32>) -> !fir.ref<i32> {dataClause = #acc<data_clause acc_reduction>, implicit = true, name = "reduction_i"}
718! CHECK:      acc.parallel {{.*}} dataOperands(%[[COPYINREDR]], %[[COPYINREDI]] : !fir.ref<f32>, !fir.ref<i32>) {
719! CHECK:        acc.loop {{.*}} reduction(@reduction_add_ref_f32 -> %{{.*}} : !fir.ref<f32>, @reduction_mul_ref_i32 -> %{{.*}} : !fir.ref<i32>) {{.*}}
720! CHECK:          acc.yield
721! CHECK-NEXT:   }{{$}}
722! CHECK:        acc.yield
723! CHECK-NEXT: }{{$}}
724! CHECK:      acc.copyout accPtr(%[[COPYINREDR]] : !fir.ref<f32>) to varPtr(%{{.*}} : !fir.ref<f32>) {dataClause = #acc<data_clause acc_reduction>, implicit = true, name = "reduction_r"}
725! CHECK:      acc.copyout accPtr(%[[COPYINREDI]] : !fir.ref<i32>) to varPtr(%{{.*}} : !fir.ref<i32>) {dataClause = #acc<data_clause acc_reduction>, implicit = true, name = "reduction_i"}
726
727
728  !$acc parallel loop
729  do 10 i=0, n
730  10 continue
731! CHECK: acc.parallel
732! CHECK: acc.loop
733! CHECK-NOT: fir.do_loop
734
735end subroutine acc_parallel_loop
736