xref: /llvm-project/flang/test/Lower/OpenACC/acc-loop.f90 (revision 26d92826a5ed7894fb6d604c8e0e755daa50cdf7)
1! This test checks lowering of OpenACC loop directive.
2
3! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s
4
5! CHECK-LABEL: acc.private.recipe @privatization_ref_10x10xf32 : !fir.ref<!fir.array<10x10xf32>> init {
6! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<10x10xf32>>):
7! CHECK: acc.yield %{{.*}} : !fir.ref<!fir.array<10x10xf32>>
8! CHECK: }
9
10program acc_loop
11
12  integer :: i, j
13  integer, parameter :: n = 10
14  real, dimension(n) :: a, b
15  real, dimension(n, n) :: c, d
16  integer :: gangNum = 8
17  integer :: gangDim = 1
18  integer :: gangStatic = 8
19  integer :: vectorLength = 128
20  integer, parameter :: tileSize = 2
21  integer :: reduction_i
22  real :: reduction_r
23
24
25  !$acc loop
26  DO i = 1, n
27    a(i) = b(i)
28  END DO
29
30! CHECK: acc.loop private(@privatization_ref_i32 -> %{{.*}} : !fir.ref<i32>) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
31! CHECK:        acc.yield
32! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>}{{$}}
33
34 !$acc loop seq
35  DO i = 1, n
36    a(i) = b(i)
37  END DO
38
39! CHECK: acc.loop private(@privatization_ref_i32 -> %{{.*}} : !fir.ref<i32>) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
40! CHECK:        acc.yield
41! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>, seq = [#acc.device_type<none>]}
42
43  !$acc loop auto
44  DO i = 1, n
45    a(i) = b(i)
46  END DO
47
48! CHECK: acc.loop private(@privatization_ref_i32 -> %{{.*}} : !fir.ref<i32>) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
49! CHECK:        acc.yield
50! CHECK-NEXT: } attributes {auto_ = [#acc.device_type<none>], inclusiveUpperbound = array<i1: true>}
51
52  !$acc loop independent
53  DO i = 1, n
54    a(i) = b(i)
55  END DO
56
57! CHECK:      acc.loop private(@privatization_ref_i32 -> %{{.*}} : !fir.ref<i32>) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
58! CHECK:        acc.yield
59! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}
60
61  !$acc loop gang
62  DO i = 1, n
63    a(i) = b(i)
64  END DO
65
66! CHECK:      acc.loop gang private(@privatization_ref_i32 -> %{{.*}} : !fir.ref<i32>) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
67! CHECK:        acc.yield
68! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>}
69
70  !$acc loop gang(num: 8)
71  DO i = 1, n
72    a(i) = b(i)
73  END DO
74
75! CHECK:      [[GANGNUM1:%.*]] = arith.constant 8 : i32
76! CHECK-NEXT: acc.loop gang({num=[[GANGNUM1]] : i32}) private(@privatization_ref_i32 -> %{{.*}} : !fir.ref<i32>) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
77! CHECK:        acc.yield
78! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>}
79
80  !$acc loop gang(num: gangNum)
81  DO i = 1, n
82    a(i) = b(i)
83  END DO
84
85! CHECK:      [[GANGNUM2:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
86! CHECK-NEXT: acc.loop gang({num=[[GANGNUM2]] : i32}) private(@privatization_ref_i32 -> %{{.*}} : !fir.ref<i32>) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
87! CHECK:        acc.yield
88! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>}
89
90 !$acc loop gang(num: gangNum, static: gangStatic)
91  DO i = 1, n
92    a(i) = b(i)
93  END DO
94
95! CHECK: acc.loop gang({num=%{{.*}} : i32, static=%{{.*}} : i32}) private(@privatization_ref_i32 -> %{{.*}} : !fir.ref<i32>) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
96! CHECK:        acc.yield
97! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>}
98
99  !$acc loop vector
100  DO i = 1, n
101    a(i) = b(i)
102  END DO
103
104! CHECK:      acc.loop vector private(@privatization_ref_i32 -> %{{.*}} : !fir.ref<i32>) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
105! CHECK:        acc.yield
106! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>}
107
108  !$acc loop vector(128)
109  DO i = 1, n
110    a(i) = b(i)
111  END DO
112
113! CHECK: [[CONSTANT128:%.*]] = arith.constant 128 : i32
114! CHECK:      acc.loop vector([[CONSTANT128]] : i32) private(@privatization_ref_i32 -> %{{.*}} : !fir.ref<i32>) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
115! CHECK:        acc.yield
116! CHECK-NEXT: }{{$}}
117
118  !$acc loop vector(vectorLength)
119  DO i = 1, n
120    a(i) = b(i)
121  END DO
122
123! CHECK:      [[VECTORLENGTH:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
124! CHECK:      acc.loop vector([[VECTORLENGTH]] : i32) private(@privatization_ref_i32 -> %{{.*}} : !fir.ref<i32>) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
125! CHECK:        acc.yield
126! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>}
127
128!$acc loop worker
129  DO i = 1, n
130    a(i) = b(i)
131  END DO
132
133! CHECK:      acc.loop worker private(@privatization_ref_i32 -> %{{.*}} : !fir.ref<i32>) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
134! CHECK:        acc.yield
135! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>}
136
137  !$acc loop worker(128)
138  DO i = 1, n
139    a(i) = b(i)
140  END DO
141
142! CHECK: [[WORKER128:%.*]] = arith.constant 128 : i32
143! CHECK:      acc.loop worker([[WORKER128]] : i32) private(@privatization_ref_i32 -> %{{.*}} : !fir.ref<i32>) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
144! CHECK:        acc.yield
145! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>}
146
147  !$acc loop private(c)
148  DO i = 1, n
149    a(i) = b(i)
150  END DO
151
152! CHECK:      acc.loop private(@privatization_ref_i32 -> %{{.*}} : !fir.ref<i32>, @privatization_ref_10x10xf32 -> %{{.*}} : !fir.ref<!fir.array<10x10xf32>>) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
153! CHECK:        acc.yield
154! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>}
155
156  !$acc loop private(c, d)
157  DO i = 1, n
158    a(i) = b(i)
159  END DO
160
161! CHECK:      acc.loop private(@privatization_ref_i32 -> %{{.*}} : !fir.ref<i32>, @privatization_ref_10x10xf32 -> %{{.*}} : !fir.ref<!fir.array<10x10xf32>>, @privatization_ref_10x10xf32 -> %{{.*}} : !fir.ref<!fir.array<10x10xf32>>) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
162! CHECK:        acc.yield
163! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>}
164
165  !$acc loop private(c) private(d)
166  DO i = 1, n
167    a(i) = b(i)
168  END DO
169
170! CHECK:      acc.loop private(@privatization_ref_i32 -> %{{.*}} : !fir.ref<i32>, @privatization_ref_10x10xf32 -> %{{.*}} : !fir.ref<!fir.array<10x10xf32>>, @privatization_ref_10x10xf32 -> %{{.*}} : !fir.ref<!fir.array<10x10xf32>>) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
171! CHECK:        acc.yield
172! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>}
173
174  !$acc loop tile(2)
175  DO i = 1, n
176    a(i) = b(i)
177  END DO
178
179! CHECK:      [[TILESIZE:%.*]] = arith.constant 2 : i32
180! CHECK:      acc.loop {{.*}} tile({[[TILESIZE]] : i32}) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
181! CHECK:        acc.yield
182! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>}
183
184 !$acc loop tile(*)
185  DO i = 1, n
186    a(i) = b(i)
187  END DO
188! CHECK:      [[TILESIZEM1:%.*]] = arith.constant -1 : i32
189! CHECK:      acc.loop {{.*}} tile({[[TILESIZEM1]] : i32}) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
190! CHECK:        acc.yield
191! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>}
192
193  !$acc loop tile(2, 2)
194  DO i = 1, n
195    DO j = 1, n
196      c(i, j) = d(i, j)
197    END DO
198  END DO
199
200! CHECK:      [[TILESIZE1:%.*]] = arith.constant 2 : i32
201! CHECK:      [[TILESIZE2:%.*]] = arith.constant 2 : i32
202! CHECK:      acc.loop {{.*}} tile({[[TILESIZE1]] : i32, [[TILESIZE2]] : i32}) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
203! CHECK:        acc.yield
204! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>}
205
206  !$acc loop tile(tileSize)
207  DO i = 1, n
208    a(i) = b(i)
209  END DO
210
211! CHECK:      acc.loop {{.*}} tile({%{{.*}} : i32}) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
212! CHECK:        acc.yield
213! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>}
214
215  !$acc loop tile(tileSize, tileSize)
216  DO i = 1, n
217    DO j = 1, n
218      c(i, j) = d(i, j)
219    END DO
220  END DO
221
222! CHECK:      acc.loop {{.*}} tile({%{{.*}} : i32, %{{.*}} : i32}) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
223! CHECK:        acc.yield
224! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>}
225
226  !$acc loop collapse(2)
227  DO i = 1, n
228    DO j = 1, n
229      c(i, j) = d(i, j)
230    END DO
231  END DO
232
233! CHECK:      acc.loop {{.*}} control(%arg0 : i32, %arg1 : i32) = (%{{.*}} : i32, i32) to (%{{.*}} : i32, i32) step (%{{.*}} : i32, i32) {
234! CHECK:        fir.store %arg0 to %{{.*}} : !fir.ref<i32>
235! CHECK:        fir.store %arg1 to %{{.*}} : !fir.ref<i32>
236! CHECK:        acc.yield
237! CHECK-NEXT: } attributes {collapse = [2], collapseDeviceType = [#acc.device_type<none>], inclusiveUpperbound = array<i1: true, true>}
238
239  !$acc loop
240  DO i = 1, n
241    !$acc loop
242    DO j = 1, n
243      c(i, j) = d(i, j)
244    END DO
245  END DO
246
247! CHECK:      acc.loop {{.*}} control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
248! CHECK:          acc.loop {{.*}} control(%arg1 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
249! CHECK:            acc.yield
250! CHECK-NEXT:   } attributes {inclusiveUpperbound = array<i1: true>}
251! CHECK:        acc.yield
252! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>}
253
254  !$acc loop reduction(+:reduction_r) reduction(*:reduction_i)
255  do i = 1, n
256    reduction_r = reduction_r + a(i)
257    reduction_i = 1
258  end do
259
260! CHECK:      acc.loop private(@privatization_ref_i32 -> %{{.*}} : !fir.ref<i32>) reduction(@reduction_add_ref_f32 -> %{{.*}} : !fir.ref<f32>, @reduction_mul_ref_i32 -> %{{.*}} : !fir.ref<i32>) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
261! CHECK:        acc.yield
262! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>}
263
264 !$acc loop gang(dim: gangDim, static: gangStatic)
265  DO i = 1, n
266    a(i) = b(i)
267  END DO
268
269! CHECK: acc.loop gang({dim=%{{.*}}, static=%{{.*}} : i32}) {{.*}} control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
270! CHECK:        acc.yield
271! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>}
272
273  !$acc loop gang(dim: 1)
274  DO i = 1, n
275    a(i) = b(i)
276  END DO
277
278! CHECK:      acc.loop gang({dim={{.*}} : i32}) {{.*}} control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) {
279! CHECK:        acc.yield
280! CHECK-NEXT: } attributes {inclusiveUpperbound = array<i1: true>}
281
282  !$acc loop
283  DO i = 1, n
284    !$acc cache(b)
285    a(i) = b(i)
286  END DO
287
288! CHECK: %[[CACHE:.*]] = acc.cache varPtr(%{{.*}} : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<10xf32>> {name = "b"}
289! CHECK: acc.loop {{.*}} cache(%[[CACHE]] : !fir.ref<!fir.array<10xf32>>)
290
291  !$acc loop
292  do 100 i=0, n
293  100 continue
294! CHECK: acc.loop
295
296  !$acc loop gang device_type(nvidia) gang(8)
297  DO i = 1, n
298  END DO
299
300! CHECK: acc.loop gang([#acc.device_type<none>], {num=%c8{{.*}} : i32} [#acc.device_type<nvidia>])
301
302  !$acc loop device_type(nvidia, default) gang
303  DO i = 1, n
304  END DO
305
306! CHECK: acc.loop gang([#acc.device_type<nvidia>, #acc.device_type<default>])
307
308end program
309
310subroutine sub1(i, j, k)
311  integer :: i,j,k
312  integer :: a(i,j,k)
313  !$acc parallel loop
314  do concurrent (i=1:10,j=1:100,k=1:200)
315    a(i,j,k) = a(i,j,k) + 1
316  end do
317end subroutine
318
319! CHECK: func.func @_QPsub1
320! CHECK: acc.parallel
321! CHECK: %[[DC_K:.*]] = fir.alloca i32 {bindc_name = "k"}
322! CHECK: %[[DC_J:.*]] = fir.alloca i32 {bindc_name = "j"}
323! CHECK: %[[DC_I:.*]] = fir.alloca i32 {bindc_name = "i"}
324! CHECK: %[[P_I:.*]] = acc.private varPtr(%[[DC_I]] : !fir.ref<i32>) -> !fir.ref<i32> {implicit = true, name = ""}
325! CHECK: %[[P_J:.*]] = acc.private varPtr(%[[DC_J]] : !fir.ref<i32>) -> !fir.ref<i32> {implicit = true, name = ""}
326! CHECK: %[[P_K:.*]] = acc.private varPtr(%[[DC_K]] : !fir.ref<i32>) -> !fir.ref<i32> {implicit = true, name = ""}
327! CHECK: acc.loop combined(parallel) private(@privatization_ref_i32 -> %[[P_I]] : !fir.ref<i32>, @privatization_ref_i32 -> %[[P_J]] : !fir.ref<i32>, @privatization_ref_i32 -> %[[P_K]] : !fir.ref<i32>) control(%{{.*}} : i32, %{{.*}} : i32, %{{.*}} : i32) = (%c1{{.*}}, %c1{{.*}}, %c1{{.*}} : i32, i32, i32) to (%c10{{.*}}, %c100{{.*}}, %c200{{.*}} : i32, i32, i32)  step (%c1{{.*}}, %c1{{.*}}, %c1{{.*}} : i32, i32, i32)
328! CHECK: } attributes {inclusiveUpperbound = array<i1: true, true, true>}
329