1// RUN: mlir-opt -split-input-file %s | FileCheck %s
2// Verify the printed output can be parsed.
3// RUN: mlir-opt -split-input-file %s | mlir-opt -allow-unregistered-dialect  | FileCheck %s
4// Verify the generic form can be parsed.
5// RUN: mlir-opt -split-input-file -mlir-print-op-generic %s | mlir-opt -allow-unregistered-dialect | FileCheck %s
6
7func @compute1(%A: memref<10x10xf32>, %B: memref<10x10xf32>, %C: memref<10x10xf32>) -> memref<10x10xf32> {
8  %c0 = constant 0 : index
9  %c10 = constant 10 : index
10  %c1 = constant 1 : index
11  %async = constant 1 : i64
12
13  acc.parallel async(%async: i64) {
14    acc.loop gang vector {
15      scf.for %arg3 = %c0 to %c10 step %c1 {
16        scf.for %arg4 = %c0 to %c10 step %c1 {
17          scf.for %arg5 = %c0 to %c10 step %c1 {
18            %a = memref.load %A[%arg3, %arg5] : memref<10x10xf32>
19            %b = memref.load %B[%arg5, %arg4] : memref<10x10xf32>
20            %cij = memref.load %C[%arg3, %arg4] : memref<10x10xf32>
21            %p = mulf %a, %b : f32
22            %co = addf %cij, %p : f32
23            memref.store %co, %C[%arg3, %arg4] : memref<10x10xf32>
24          }
25        }
26      }
27      acc.yield
28    } attributes { collapse = 3 }
29    acc.yield
30  }
31
32  return %C : memref<10x10xf32>
33}
34
35// CHECK-LABEL: func @compute1(
36//  CHECK-NEXT:   %{{.*}} = constant 0 : index
37//  CHECK-NEXT:   %{{.*}} = constant 10 : index
38//  CHECK-NEXT:   %{{.*}} = constant 1 : index
39//  CHECK-NEXT:   [[ASYNC:%.*]] = constant 1 : i64
40//  CHECK-NEXT:   acc.parallel async([[ASYNC]]: i64) {
41//  CHECK-NEXT:     acc.loop gang vector {
42//  CHECK-NEXT:       scf.for %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} {
43//  CHECK-NEXT:         scf.for %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} {
44//  CHECK-NEXT:           scf.for %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} {
45//  CHECK-NEXT:             %{{.*}} = memref.load %{{.*}}[%{{.*}}, %{{.*}}] : memref<10x10xf32>
46//  CHECK-NEXT:             %{{.*}} = memref.load %{{.*}}[%{{.*}}, %{{.*}}] : memref<10x10xf32>
47//  CHECK-NEXT:             %{{.*}} = memref.load %{{.*}}[%{{.*}}, %{{.*}}] : memref<10x10xf32>
48//  CHECK-NEXT:             %{{.*}} = mulf %{{.*}}, %{{.*}} : f32
49//  CHECK-NEXT:             %{{.*}} = addf %{{.*}}, %{{.*}} : f32
50//  CHECK-NEXT:             memref.store %{{.*}}, %{{.*}}[%{{.*}}, %{{.*}}] : memref<10x10xf32>
51//  CHECK-NEXT:           }
52//  CHECK-NEXT:         }
53//  CHECK-NEXT:       }
54//  CHECK-NEXT:       acc.yield
55//  CHECK-NEXT:     } attributes {collapse = 3 : i64}
56//  CHECK-NEXT:     acc.yield
57//  CHECK-NEXT:   }
58//  CHECK-NEXT:   return %{{.*}} : memref<10x10xf32>
59//  CHECK-NEXT: }
60
61// -----
62
63func @compute2(%A: memref<10x10xf32>, %B: memref<10x10xf32>, %C: memref<10x10xf32>) -> memref<10x10xf32> {
64  %c0 = constant 0 : index
65  %c10 = constant 10 : index
66  %c1 = constant 1 : index
67
68  acc.parallel {
69    acc.loop {
70      scf.for %arg3 = %c0 to %c10 step %c1 {
71        scf.for %arg4 = %c0 to %c10 step %c1 {
72          scf.for %arg5 = %c0 to %c10 step %c1 {
73            %a = memref.load %A[%arg3, %arg5] : memref<10x10xf32>
74            %b = memref.load %B[%arg5, %arg4] : memref<10x10xf32>
75            %cij = memref.load %C[%arg3, %arg4] : memref<10x10xf32>
76            %p = mulf %a, %b : f32
77            %co = addf %cij, %p : f32
78            memref.store %co, %C[%arg3, %arg4] : memref<10x10xf32>
79          }
80        }
81      }
82      acc.yield
83    } attributes {seq}
84    acc.yield
85  }
86
87  return %C : memref<10x10xf32>
88}
89
90// CHECK-LABEL: func @compute2(
91//  CHECK-NEXT:   %{{.*}} = constant 0 : index
92//  CHECK-NEXT:   %{{.*}} = constant 10 : index
93//  CHECK-NEXT:   %{{.*}} = constant 1 : index
94//  CHECK-NEXT:   acc.parallel {
95//  CHECK-NEXT:     acc.loop {
96//  CHECK-NEXT:       scf.for %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} {
97//  CHECK-NEXT:         scf.for %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} {
98//  CHECK-NEXT:           scf.for %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} {
99//  CHECK-NEXT:             %{{.*}} = memref.load %{{.*}}[%{{.*}}, %{{.*}}] : memref<10x10xf32>
100//  CHECK-NEXT:             %{{.*}} = memref.load %{{.*}}[%{{.*}}, %{{.*}}] : memref<10x10xf32>
101//  CHECK-NEXT:             %{{.*}} = memref.load %{{.*}}[%{{.*}}, %{{.*}}] : memref<10x10xf32>
102//  CHECK-NEXT:             %{{.*}} = mulf %{{.*}}, %{{.*}} : f32
103//  CHECK-NEXT:             %{{.*}} = addf %{{.*}}, %{{.*}} : f32
104//  CHECK-NEXT:             memref.store %{{.*}}, %{{.*}}[%{{.*}}, %{{.*}}] : memref<10x10xf32>
105//  CHECK-NEXT:           }
106//  CHECK-NEXT:         }
107//  CHECK-NEXT:       }
108//  CHECK-NEXT:       acc.yield
109//  CHECK-NEXT:     } attributes {seq}
110//  CHECK-NEXT:     acc.yield
111//  CHECK-NEXT:   }
112//  CHECK-NEXT:   return %{{.*}} : memref<10x10xf32>
113//  CHECK-NEXT: }
114
115// -----
116
117func @compute3(%a: memref<10x10xf32>, %b: memref<10x10xf32>, %c: memref<10xf32>, %d: memref<10xf32>) -> memref<10xf32> {
118  %lb = constant 0 : index
119  %st = constant 1 : index
120  %c10 = constant 10 : index
121  %numGangs = constant 10 : i64
122  %numWorkers = constant 10 : i64
123
124  acc.data present(%a, %b, %c, %d: memref<10x10xf32>, memref<10x10xf32>, memref<10xf32>, memref<10xf32>) {
125    acc.parallel num_gangs(%numGangs: i64) num_workers(%numWorkers: i64) private(%c : memref<10xf32>) {
126      acc.loop gang {
127        scf.for %x = %lb to %c10 step %st {
128          acc.loop worker {
129            scf.for %y = %lb to %c10 step %st {
130              %axy = memref.load %a[%x, %y] : memref<10x10xf32>
131              %bxy = memref.load %b[%x, %y] : memref<10x10xf32>
132              %tmp = addf %axy, %bxy : f32
133              memref.store %tmp, %c[%y] : memref<10xf32>
134            }
135            acc.yield
136          }
137
138          acc.loop {
139            // for i = 0 to 10 step 1
140            //   d[x] += c[i]
141            scf.for %i = %lb to %c10 step %st {
142              %ci = memref.load %c[%i] : memref<10xf32>
143              %dx = memref.load %d[%x] : memref<10xf32>
144              %z = addf %ci, %dx : f32
145              memref.store %z, %d[%x] : memref<10xf32>
146            }
147            acc.yield
148          } attributes {seq}
149        }
150        acc.yield
151      }
152      acc.yield
153    }
154    acc.terminator
155  }
156
157  return %d : memref<10xf32>
158}
159
160// CHECK:      func @compute3({{.*}}: memref<10x10xf32>, {{.*}}: memref<10x10xf32>, [[ARG2:%.*]]: memref<10xf32>, {{.*}}: memref<10xf32>) -> memref<10xf32> {
161// CHECK-NEXT:   [[C0:%.*]] = constant 0 : index
162// CHECK-NEXT:   [[C1:%.*]] = constant 1 : index
163// CHECK-NEXT:   [[C10:%.*]] = constant 10 : index
164// CHECK-NEXT:   [[NUMGANG:%.*]] = constant 10 : i64
165// CHECK-NEXT:   [[NUMWORKERS:%.*]] = constant 10 : i64
166// CHECK-NEXT:   acc.data present(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}} : memref<10x10xf32>, memref<10x10xf32>, memref<10xf32>, memref<10xf32>) {
167// CHECK-NEXT:     acc.parallel num_gangs([[NUMGANG]]: i64) num_workers([[NUMWORKERS]]: i64) private([[ARG2]]: memref<10xf32>) {
168// CHECK-NEXT:       acc.loop gang {
169// CHECK-NEXT:         scf.for %{{.*}} = [[C0]] to [[C10]] step [[C1]] {
170// CHECK-NEXT:           acc.loop worker {
171// CHECK-NEXT:             scf.for %{{.*}} = [[C0]] to [[C10]] step [[C1]] {
172// CHECK-NEXT:               %{{.*}} = memref.load %{{.*}}[%{{.*}}, %{{.*}}] : memref<10x10xf32>
173// CHECK-NEXT:               %{{.*}} = memref.load %{{.*}}[%{{.*}}, %{{.*}}] : memref<10x10xf32>
174// CHECK-NEXT:               %{{.*}} = addf %{{.*}}, %{{.*}} : f32
175// CHECK-NEXT:               memref.store %{{.*}}, %{{.*}}[%{{.*}}] : memref<10xf32>
176// CHECK-NEXT:             }
177// CHECK-NEXT:             acc.yield
178// CHECK-NEXT:           }
179// CHECK-NEXT:           acc.loop {
180// CHECK-NEXT:             scf.for %{{.*}} = [[C0]] to [[C10]] step [[C1]] {
181// CHECK-NEXT:               %{{.*}} = memref.load %{{.*}}[%{{.*}}] : memref<10xf32>
182// CHECK-NEXT:               %{{.*}} = memref.load %{{.*}}[%{{.*}}] : memref<10xf32>
183// CHECK-NEXT:               %{{.*}} = addf %{{.*}}, %{{.*}} : f32
184// CHECK-NEXT:               memref.store %{{.*}}, %{{.*}}[%{{.*}}] : memref<10xf32>
185// CHECK-NEXT:             }
186// CHECK-NEXT:             acc.yield
187// CHECK-NEXT:           } attributes {seq}
188// CHECK-NEXT:         }
189// CHECK-NEXT:         acc.yield
190// CHECK-NEXT:       }
191// CHECK-NEXT:       acc.yield
192// CHECK-NEXT:     }
193// CHECK-NEXT:     acc.terminator
194// CHECK-NEXT:   }
195// CHECK-NEXT:   return %{{.*}} : memref<10xf32>
196// CHECK-NEXT: }
197
198// -----
199
200func @testloopop() -> () {
201  %i64Value = constant 1 : i64
202  %i32Value = constant 128 : i32
203  %idxValue = constant 8 : index
204
205  acc.loop gang worker vector {
206    "test.openacc_dummy_op"() : () -> ()
207    acc.yield
208  }
209  acc.loop gang(num=%i64Value: i64) {
210    "test.openacc_dummy_op"() : () -> ()
211    acc.yield
212  }
213  acc.loop gang(static=%i64Value: i64) {
214    "test.openacc_dummy_op"() : () -> ()
215    acc.yield
216  }
217  acc.loop worker(%i64Value: i64) {
218    "test.openacc_dummy_op"() : () -> ()
219    acc.yield
220  }
221  acc.loop worker(%i32Value: i32) {
222    "test.openacc_dummy_op"() : () -> ()
223    acc.yield
224  }
225  acc.loop worker(%idxValue: index) {
226    "test.openacc_dummy_op"() : () -> ()
227    acc.yield
228  }
229  acc.loop vector(%i64Value: i64) {
230    "test.openacc_dummy_op"() : () -> ()
231    acc.yield
232  }
233  acc.loop vector(%i32Value: i32) {
234    "test.openacc_dummy_op"() : () -> ()
235    acc.yield
236  }
237  acc.loop vector(%idxValue: index) {
238    "test.openacc_dummy_op"() : () -> ()
239    acc.yield
240  }
241  acc.loop gang(num=%i64Value: i64) worker vector {
242    "test.openacc_dummy_op"() : () -> ()
243    acc.yield
244  }
245  acc.loop gang(num=%i64Value: i64, static=%i64Value: i64) worker(%i64Value: i64) vector(%i64Value: i64) {
246    "test.openacc_dummy_op"() : () -> ()
247    acc.yield
248  }
249  acc.loop gang(num=%i32Value: i32, static=%idxValue: index) {
250    "test.openacc_dummy_op"() : () -> ()
251    acc.yield
252  }
253  acc.loop tile(%i64Value: i64, %i64Value: i64) {
254    "test.openacc_dummy_op"() : () -> ()
255    acc.yield
256  }
257  acc.loop tile(%i32Value: i32, %i32Value: i32) {
258    "test.openacc_dummy_op"() : () -> ()
259    acc.yield
260  }
261  return
262}
263
264// CHECK:      [[I64VALUE:%.*]] = constant 1 : i64
265// CHECK-NEXT: [[I32VALUE:%.*]] = constant 128 : i32
266// CHECK-NEXT: [[IDXVALUE:%.*]] = constant 8 : index
267// CHECK:      acc.loop gang worker vector {
268// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()
269// CHECK-NEXT:   acc.yield
270// CHECK-NEXT: }
271// CHECK:      acc.loop gang(num=[[I64VALUE]]: i64) {
272// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()
273// CHECK-NEXT:   acc.yield
274// CHECK-NEXT: }
275// CHECK:      acc.loop gang(static=[[I64VALUE]]: i64) {
276// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()
277// CHECK-NEXT:   acc.yield
278// CHECK-NEXT: }
279// CHECK:      acc.loop worker([[I64VALUE]]: i64) {
280// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()
281// CHECK-NEXT:   acc.yield
282// CHECK-NEXT: }
283// CHECK:      acc.loop worker([[I32VALUE]]: i32) {
284// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()
285// CHECK-NEXT:   acc.yield
286// CHECK-NEXT: }
287// CHECK:      acc.loop worker([[IDXVALUE]]: index) {
288// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()
289// CHECK-NEXT:   acc.yield
290// CHECK-NEXT: }
291// CHECK:      acc.loop vector([[I64VALUE]]: i64) {
292// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()
293// CHECK-NEXT:   acc.yield
294// CHECK-NEXT: }
295// CHECK:      acc.loop vector([[I32VALUE]]: i32) {
296// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()
297// CHECK-NEXT:   acc.yield
298// CHECK-NEXT: }
299// CHECK:      acc.loop vector([[IDXVALUE]]: index) {
300// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()
301// CHECK-NEXT:   acc.yield
302// CHECK-NEXT: }
303// CHECK:      acc.loop gang(num=[[I64VALUE]]: i64) worker vector {
304// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()
305// CHECK-NEXT:   acc.yield
306// CHECK-NEXT: }
307// CHECK:      acc.loop gang(num=[[I64VALUE]]: i64, static=[[I64VALUE]]: i64) worker([[I64VALUE]]: i64) vector([[I64VALUE]]: i64) {
308// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()
309// CHECK-NEXT:   acc.yield
310// CHECK-NEXT: }
311// CHECK:      acc.loop gang(num=[[I32VALUE]]: i32, static=[[IDXVALUE]]: index) {
312// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()
313// CHECK-NEXT:   acc.yield
314// CHECK-NEXT: }
315// CHECK:      acc.loop tile([[I64VALUE]]: i64, [[I64VALUE]]: i64) {
316// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()
317// CHECK-NEXT:   acc.yield
318// CHECK-NEXT: }
319// CHECK:      acc.loop tile([[I32VALUE]]: i32, [[I32VALUE]]: i32) {
320// CHECK-NEXT:   "test.openacc_dummy_op"() : () -> ()
321// CHECK-NEXT:   acc.yield
322// CHECK-NEXT: }
323
324// -----
325
326func @testparallelop(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32>) -> () {
327  %i64value = constant 1 : i64
328  %i32value = constant 1 : i32
329  %idxValue = constant 1 : index
330  acc.parallel async(%i64value: i64) {
331  }
332  acc.parallel async(%i32value: i32) {
333  }
334  acc.parallel async(%idxValue: index) {
335  }
336  acc.parallel wait(%i64value: i64) {
337  }
338  acc.parallel wait(%i32value: i32) {
339  }
340  acc.parallel wait(%idxValue: index) {
341  }
342  acc.parallel wait(%i64value: i64, %i32value: i32, %idxValue: index) {
343  }
344  acc.parallel num_gangs(%i64value: i64) {
345  }
346  acc.parallel num_gangs(%i32value: i32) {
347  }
348  acc.parallel num_gangs(%idxValue: index) {
349  }
350  acc.parallel num_workers(%i64value: i64) {
351  }
352  acc.parallel num_workers(%i32value: i32) {
353  }
354  acc.parallel num_workers(%idxValue: index) {
355  }
356  acc.parallel vector_length(%i64value: i64) {
357  }
358  acc.parallel vector_length(%i32value: i32) {
359  }
360  acc.parallel vector_length(%idxValue: index) {
361  }
362  acc.parallel copyin(%a: memref<10xf32>, %b: memref<10xf32>) {
363  }
364  acc.parallel copyin_readonly(%a: memref<10xf32>, %b: memref<10xf32>) {
365  }
366  acc.parallel copyin(%a: memref<10xf32>) copyout_zero(%b: memref<10xf32>, %c: memref<10x10xf32>) {
367  }
368  acc.parallel copyout(%b: memref<10xf32>, %c: memref<10x10xf32>) create(%a: memref<10xf32>) {
369  }
370  acc.parallel copyout_zero(%b: memref<10xf32>, %c: memref<10x10xf32>) create_zero(%a: memref<10xf32>) {
371  }
372  acc.parallel no_create(%a: memref<10xf32>) present(%b: memref<10xf32>, %c: memref<10x10xf32>) {
373  }
374  acc.parallel deviceptr(%a: memref<10xf32>) attach(%b: memref<10xf32>, %c: memref<10x10xf32>) {
375  }
376  acc.parallel private(%a: memref<10xf32>, %c: memref<10x10xf32>) firstprivate(%b: memref<10xf32>) {
377  }
378  acc.parallel {
379  } attributes {defaultAttr = "none"}
380  acc.parallel {
381  } attributes {defaultAttr = "present"}
382  acc.parallel {
383  } attributes {asyncAttr}
384  acc.parallel {
385  } attributes {waitAttr}
386  acc.parallel {
387  } attributes {selfAttr}
388  return
389}
390
391// CHECK:      func @testparallelop([[ARGA:%.*]]: memref<10xf32>, [[ARGB:%.*]]: memref<10xf32>, [[ARGC:%.*]]: memref<10x10xf32>) {
392// CHECK:      [[I64VALUE:%.*]] = constant 1 : i64
393// CHECK:      [[I32VALUE:%.*]] = constant 1 : i32
394// CHECK:      [[IDXVALUE:%.*]] = constant 1 : index
395// CHECK:      acc.parallel async([[I64VALUE]]: i64) {
396// CHECK-NEXT: }
397// CHECK:      acc.parallel async([[I32VALUE]]: i32) {
398// CHECK-NEXT: }
399// CHECK:      acc.parallel async([[IDXVALUE]]: index) {
400// CHECK-NEXT: }
401// CHECK:      acc.parallel wait([[I64VALUE]]: i64) {
402// CHECK-NEXT: }
403// CHECK:      acc.parallel wait([[I32VALUE]]: i32) {
404// CHECK-NEXT: }
405// CHECK:      acc.parallel wait([[IDXVALUE]]: index) {
406// CHECK-NEXT: }
407// CHECK:      acc.parallel wait([[I64VALUE]]: i64, [[I32VALUE]]: i32, [[IDXVALUE]]: index) {
408// CHECK-NEXT: }
409// CHECK:      acc.parallel num_gangs([[I64VALUE]]: i64) {
410// CHECK-NEXT: }
411// CHECK:      acc.parallel num_gangs([[I32VALUE]]: i32) {
412// CHECK-NEXT: }
413// CHECK:      acc.parallel num_gangs([[IDXVALUE]]: index) {
414// CHECK-NEXT: }
415// CHECK:      acc.parallel num_workers([[I64VALUE]]: i64) {
416// CHECK-NEXT: }
417// CHECK:      acc.parallel num_workers([[I32VALUE]]: i32) {
418// CHECK-NEXT: }
419// CHECK:      acc.parallel num_workers([[IDXVALUE]]: index) {
420// CHECK-NEXT: }
421// CHECK:      acc.parallel vector_length([[I64VALUE]]: i64) {
422// CHECK-NEXT: }
423// CHECK:      acc.parallel vector_length([[I32VALUE]]: i32) {
424// CHECK-NEXT: }
425// CHECK:      acc.parallel vector_length([[IDXVALUE]]: index) {
426// CHECK-NEXT: }
427// CHECK:      acc.parallel copyin([[ARGA]]: memref<10xf32>, [[ARGB]]: memref<10xf32>) {
428// CHECK-NEXT: }
429// CHECK:      acc.parallel copyin_readonly([[ARGA]]: memref<10xf32>, [[ARGB]]: memref<10xf32>) {
430// CHECK-NEXT: }
431// CHECK:      acc.parallel copyin([[ARGA]]: memref<10xf32>) copyout_zero([[ARGB]]: memref<10xf32>, [[ARGC]]: memref<10x10xf32>) {
432// CHECK-NEXT: }
433// CHECK:      acc.parallel copyout([[ARGB]]: memref<10xf32>, [[ARGC]]: memref<10x10xf32>) create([[ARGA]]: memref<10xf32>) {
434// CHECK-NEXT: }
435// CHECK:      acc.parallel copyout_zero([[ARGB]]: memref<10xf32>, [[ARGC]]: memref<10x10xf32>) create_zero([[ARGA]]: memref<10xf32>) {
436// CHECK-NEXT: }
437// CHECK:      acc.parallel no_create([[ARGA]]: memref<10xf32>) present([[ARGB]]: memref<10xf32>, [[ARGC]]: memref<10x10xf32>) {
438// CHECK-NEXT: }
439// CHECK:      acc.parallel deviceptr([[ARGA]]: memref<10xf32>) attach([[ARGB]]: memref<10xf32>, [[ARGC]]: memref<10x10xf32>) {
440// CHECK-NEXT: }
441// CHECK:      acc.parallel private([[ARGA]]: memref<10xf32>, [[ARGC]]: memref<10x10xf32>) firstprivate([[ARGB]]: memref<10xf32>) {
442// CHECK-NEXT: }
443// CHECK:      acc.parallel {
444// CHECK-NEXT: } attributes {defaultAttr = "none"}
445// CHECK:      acc.parallel {
446// CHECK-NEXT: } attributes {defaultAttr = "present"}
447// CHECK:      acc.parallel {
448// CHECK-NEXT: } attributes {asyncAttr}
449// CHECK:      acc.parallel {
450// CHECK-NEXT: } attributes {waitAttr}
451// CHECK:      acc.parallel {
452// CHECK-NEXT: } attributes {selfAttr}
453
454// -----
455
456func @testdataop(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32>) -> () {
457  %ifCond = constant true
458  acc.data if(%ifCond) present(%a : memref<10xf32>) {
459  }
460  acc.data present(%a, %b, %c : memref<10xf32>, memref<10xf32>, memref<10x10xf32>) {
461  }
462  acc.data copy(%a, %b, %c : memref<10xf32>, memref<10xf32>, memref<10x10xf32>) {
463  }
464  acc.data copyin(%a, %b, %c : memref<10xf32>, memref<10xf32>, memref<10x10xf32>) {
465  }
466  acc.data copyin_readonly(%a, %b, %c : memref<10xf32>, memref<10xf32>, memref<10x10xf32>) {
467  }
468  acc.data copyout(%a, %b, %c : memref<10xf32>, memref<10xf32>, memref<10x10xf32>) {
469  }
470  acc.data copyout_zero(%a, %b, %c : memref<10xf32>, memref<10xf32>, memref<10x10xf32>) {
471  }
472  acc.data create(%a, %b, %c : memref<10xf32>, memref<10xf32>, memref<10x10xf32>) {
473  }
474  acc.data create_zero(%a, %b, %c : memref<10xf32>, memref<10xf32>, memref<10x10xf32>) {
475  }
476  acc.data no_create(%a, %b, %c : memref<10xf32>, memref<10xf32>, memref<10x10xf32>) {
477  }
478  acc.data deviceptr(%a, %b, %c : memref<10xf32>, memref<10xf32>, memref<10x10xf32>) {
479  }
480  acc.data attach(%a, %b, %c : memref<10xf32>, memref<10xf32>, memref<10x10xf32>) {
481  }
482  acc.data copyin(%b: memref<10xf32>) copyout(%c: memref<10x10xf32>) present(%a: memref<10xf32>) {
483  }
484  acc.data present(%a : memref<10xf32>) {
485  } attributes { defaultAttr = "none" }
486  acc.data present(%a : memref<10xf32>) {
487  } attributes { defaultAttr = "present" }
488  acc.data {
489  } attributes { defaultAttr = "none" }
490  return
491}
492
493// CHECK:      func @testdataop([[ARGA:%.*]]: memref<10xf32>, [[ARGB:%.*]]: memref<10xf32>, [[ARGC:%.*]]: memref<10x10xf32>) {
494// CHECK:      [[IFCOND1:%.*]] = constant true
495// CHECK:      acc.data if([[IFCOND1]]) present([[ARGA]] : memref<10xf32>) {
496// CHECK-NEXT: }
497// CHECK:      acc.data present([[ARGA]], [[ARGB]], [[ARGC]] : memref<10xf32>, memref<10xf32>, memref<10x10xf32>) {
498// CHECK-NEXT: }
499// CHECK:      acc.data copy([[ARGA]], [[ARGB]], [[ARGC]] : memref<10xf32>, memref<10xf32>, memref<10x10xf32>) {
500// CHECK-NEXT: }
501// CHECK:      acc.data copyin([[ARGA]], [[ARGB]], [[ARGC]] : memref<10xf32>, memref<10xf32>, memref<10x10xf32>) {
502// CHECK-NEXT: }
503// CHECK:      acc.data copyin_readonly([[ARGA]], [[ARGB]], [[ARGC]] : memref<10xf32>, memref<10xf32>, memref<10x10xf32>) {
504// CHECK-NEXT: }
505// CHECK:      acc.data copyout([[ARGA]], [[ARGB]], [[ARGC]] : memref<10xf32>, memref<10xf32>, memref<10x10xf32>) {
506// CHECK-NEXT: }
507// CHECK:      acc.data copyout_zero([[ARGA]], [[ARGB]], [[ARGC]] : memref<10xf32>, memref<10xf32>, memref<10x10xf32>) {
508// CHECK-NEXT: }
509// CHECK:      acc.data create([[ARGA]], [[ARGB]], [[ARGC]] : memref<10xf32>, memref<10xf32>, memref<10x10xf32>) {
510// CHECK-NEXT: }
511// CHECK:      acc.data create_zero([[ARGA]], [[ARGB]], [[ARGC]] : memref<10xf32>, memref<10xf32>, memref<10x10xf32>) {
512// CHECK-NEXT: }
513// CHECK:      acc.data no_create([[ARGA]], [[ARGB]], [[ARGC]] : memref<10xf32>, memref<10xf32>, memref<10x10xf32>) {
514// CHECK-NEXT: }
515// CHECK:      acc.data deviceptr([[ARGA]], [[ARGB]], [[ARGC]] : memref<10xf32>, memref<10xf32>, memref<10x10xf32>) {
516// CHECK-NEXT: }
517// CHECK:      acc.data attach([[ARGA]], [[ARGB]], [[ARGC]] : memref<10xf32>, memref<10xf32>, memref<10x10xf32>) {
518// CHECK-NEXT: }
519// CHECK:      acc.data copyin([[ARGB]] : memref<10xf32>) copyout([[ARGC]] : memref<10x10xf32>) present([[ARGA]] : memref<10xf32>) {
520// CHECK-NEXT: }
521// CHECK:      acc.data present([[ARGA]] : memref<10xf32>) {
522// CHECK-NEXT: } attributes {defaultAttr = "none"}
523// CHECK:      acc.data present([[ARGA]] : memref<10xf32>) {
524// CHECK-NEXT: } attributes {defaultAttr = "present"}
525// CHECK:      acc.data {
526// CHECK-NEXT: } attributes {defaultAttr = "none"}
527
528// -----
529
530func @testupdateop(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32>) -> () {
531  %i64Value = constant 1 : i64
532  %i32Value = constant 1 : i32
533  %idxValue = constant 1 : index
534  %ifCond = constant true
535  acc.update async(%i64Value: i64) host(%a: memref<10xf32>)
536  acc.update async(%i32Value: i32) host(%a: memref<10xf32>)
537  acc.update async(%idxValue: index) host(%a: memref<10xf32>)
538  acc.update wait_devnum(%i64Value: i64) wait(%i32Value, %idxValue : i32, index) host(%a: memref<10xf32>)
539  acc.update if(%ifCond) host(%a: memref<10xf32>)
540  acc.update device_type(%i32Value : i32) host(%a: memref<10xf32>)
541  acc.update host(%a: memref<10xf32>) device(%b, %c : memref<10xf32>, memref<10x10xf32>)
542  acc.update host(%a: memref<10xf32>) device(%b, %c : memref<10xf32>, memref<10x10xf32>) attributes {async}
543  acc.update host(%a: memref<10xf32>) device(%b, %c : memref<10xf32>, memref<10x10xf32>) attributes {wait}
544  acc.update host(%a: memref<10xf32>) device(%b, %c : memref<10xf32>, memref<10x10xf32>) attributes {ifPresent}
545  return
546}
547
548// CHECK: func @testupdateop([[ARGA:%.*]]: memref<10xf32>, [[ARGB:%.*]]: memref<10xf32>, [[ARGC:%.*]]: memref<10x10xf32>) {
549// CHECK:   [[I64VALUE:%.*]] = constant 1 : i64
550// CHECK:   [[I32VALUE:%.*]] = constant 1 : i32
551// CHECK:   [[IDXVALUE:%.*]] = constant 1 : index
552// CHECK:   [[IFCOND:%.*]] = constant true
553// CHECK:   acc.update async([[I64VALUE]] : i64) host([[ARGA]] : memref<10xf32>)
554// CHECK:   acc.update async([[I32VALUE]] : i32) host([[ARGA]] : memref<10xf32>)
555// CHECK:   acc.update async([[IDXVALUE]] : index) host([[ARGA]] : memref<10xf32>)
556// CHECK:   acc.update wait_devnum([[I64VALUE]] : i64) wait([[I32VALUE]], [[IDXVALUE]] : i32, index) host([[ARGA]] : memref<10xf32>)
557// CHECK:   acc.update if([[IFCOND]]) host([[ARGA]] : memref<10xf32>)
558// CHECK:   acc.update device_type([[I32VALUE]] : i32) host([[ARGA]] : memref<10xf32>)
559// CHECK:   acc.update host([[ARGA]] : memref<10xf32>) device([[ARGB]], [[ARGC]] : memref<10xf32>, memref<10x10xf32>)
560// CHECK:   acc.update host([[ARGA]] : memref<10xf32>) device([[ARGB]], [[ARGC]] : memref<10xf32>, memref<10x10xf32>) attributes {async}
561// CHECK:   acc.update host([[ARGA]] : memref<10xf32>) device([[ARGB]], [[ARGC]] : memref<10xf32>, memref<10x10xf32>) attributes {wait}
562// CHECK:   acc.update host([[ARGA]] : memref<10xf32>) device([[ARGB]], [[ARGC]] : memref<10xf32>, memref<10x10xf32>) attributes {ifPresent}
563
564// -----
565
566%i64Value = constant 1 : i64
567%i32Value = constant 1 : i32
568%idxValue = constant 1 : index
569%ifCond = constant true
570acc.wait
571acc.wait(%i64Value: i64)
572acc.wait(%i32Value: i32)
573acc.wait(%idxValue: index)
574acc.wait(%i32Value, %idxValue : i32, index)
575acc.wait async(%i64Value: i64)
576acc.wait async(%i32Value: i32)
577acc.wait async(%idxValue: index)
578acc.wait(%i32Value: i32) async(%idxValue: index)
579acc.wait(%i64Value: i64) wait_devnum(%i32Value: i32)
580acc.wait attributes {async}
581acc.wait(%i64Value: i64) async(%idxValue: index) wait_devnum(%i32Value: i32)
582acc.wait if(%ifCond)
583
584// CHECK: [[I64VALUE:%.*]] = constant 1 : i64
585// CHECK: [[I32VALUE:%.*]] = constant 1 : i32
586// CHECK: [[IDXVALUE:%.*]] = constant 1 : index
587// CHECK: [[IFCOND:%.*]] = constant true
588// CHECK: acc.wait
589// CHECK: acc.wait([[I64VALUE]] : i64)
590// CHECK: acc.wait([[I32VALUE]] : i32)
591// CHECK: acc.wait([[IDXVALUE]] : index)
592// CHECK: acc.wait([[I32VALUE]], [[IDXVALUE]] : i32, index)
593// CHECK: acc.wait async([[I64VALUE]] : i64)
594// CHECK: acc.wait async([[I32VALUE]] : i32)
595// CHECK: acc.wait async([[IDXVALUE]] : index)
596// CHECK: acc.wait([[I32VALUE]] : i32) async([[IDXVALUE]] : index)
597// CHECK: acc.wait([[I64VALUE]] : i64) wait_devnum([[I32VALUE]] : i32)
598// CHECK: acc.wait attributes {async}
599// CHECK: acc.wait([[I64VALUE]] : i64) async([[IDXVALUE]] : index) wait_devnum([[I32VALUE]] : i32)
600// CHECK: acc.wait if([[IFCOND]])
601
602// -----
603
604%i64Value = constant 1 : i64
605%i32Value = constant 1 : i32
606%i32Value2 = constant 2 : i32
607%idxValue = constant 1 : index
608%ifCond = constant true
609acc.init
610acc.init device_type(%i32Value : i32)
611acc.init device_type(%i32Value, %i32Value2 : i32, i32)
612acc.init device_num(%i64Value : i64)
613acc.init device_num(%i32Value : i32)
614acc.init device_num(%idxValue : index)
615acc.init if(%ifCond)
616
617// CHECK: [[I64VALUE:%.*]] = constant 1 : i64
618// CHECK: [[I32VALUE:%.*]] = constant 1 : i32
619// CHECK: [[I32VALUE2:%.*]] = constant 2 : i32
620// CHECK: [[IDXVALUE:%.*]] = constant 1 : index
621// CHECK: [[IFCOND:%.*]] = constant true
622// CHECK: acc.init
623// CHECK: acc.init device_type([[I32VALUE]] : i32)
624// CHECK: acc.init device_type([[I32VALUE]], [[I32VALUE2]] : i32, i32)
625// CHECK: acc.init device_num([[I64VALUE]] : i64)
626// CHECK: acc.init device_num([[I32VALUE]] : i32)
627// CHECK: acc.init device_num([[IDXVALUE]] : index)
628// CHECK: acc.init if([[IFCOND]])
629
630// -----
631
632%i64Value = constant 1 : i64
633%i32Value = constant 1 : i32
634%i32Value2 = constant 2 : i32
635%idxValue = constant 1 : index
636%ifCond = constant true
637acc.shutdown
638acc.shutdown device_type(%i32Value : i32)
639acc.shutdown device_type(%i32Value, %i32Value2 : i32, i32)
640acc.shutdown device_num(%i64Value : i64)
641acc.shutdown device_num(%i32Value : i32)
642acc.shutdown device_num(%idxValue : index)
643acc.shutdown if(%ifCond)
644
645// CHECK: [[I64VALUE:%.*]] = constant 1 : i64
646// CHECK: [[I32VALUE:%.*]] = constant 1 : i32
647// CHECK: [[I32VALUE2:%.*]] = constant 2 : i32
648// CHECK: [[IDXVALUE:%.*]] = constant 1 : index
649// CHECK: [[IFCOND:%.*]] = constant true
650// CHECK: acc.shutdown
651// CHECK: acc.shutdown device_type([[I32VALUE]] : i32)
652// CHECK: acc.shutdown device_type([[I32VALUE]], [[I32VALUE2]] : i32, i32)
653// CHECK: acc.shutdown device_num([[I64VALUE]] : i64)
654// CHECK: acc.shutdown device_num([[I32VALUE]] : i32)
655// CHECK: acc.shutdown device_num([[IDXVALUE]] : index)
656// CHECK: acc.shutdown if([[IFCOND]])
657
658// -----
659
660func @testexitdataop(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32>) -> () {
661  %ifCond = constant true
662  %i64Value = constant 1 : i64
663  %i32Value = constant 1 : i32
664  %idxValue = constant 1 : index
665
666  acc.exit_data copyout(%a : memref<10xf32>)
667  acc.exit_data delete(%a : memref<10xf32>)
668  acc.exit_data delete(%a : memref<10xf32>) attributes {async,finalize}
669  acc.exit_data detach(%a : memref<10xf32>)
670  acc.exit_data copyout(%a : memref<10xf32>) attributes {async}
671  acc.exit_data delete(%a : memref<10xf32>) attributes {wait}
672  acc.exit_data async(%i64Value : i64) copyout(%a : memref<10xf32>)
673  acc.exit_data if(%ifCond) copyout(%a : memref<10xf32>)
674  acc.exit_data wait_devnum(%i64Value: i64) wait(%i32Value, %idxValue : i32, index) copyout(%a : memref<10xf32>)
675
676  return
677}
678
679// CHECK: func @testexitdataop([[ARGA:%.*]]: memref<10xf32>, [[ARGB:%.*]]: memref<10xf32>, [[ARGC:%.*]]: memref<10x10xf32>) {
680// CHECK: [[IFCOND1:%.*]] = constant true
681// CHECK: [[I64VALUE:%.*]] = constant 1 : i64
682// CHECK: [[I32VALUE:%.*]] = constant 1 : i32
683// CHECK: [[IDXVALUE:%.*]] = constant 1 : index
684// CHECK: acc.exit_data copyout([[ARGA]] : memref<10xf32>)
685// CHECK: acc.exit_data delete([[ARGA]] : memref<10xf32>)
686// CHECK: acc.exit_data delete([[ARGA]] : memref<10xf32>) attributes {async, finalize}
687// CHECK: acc.exit_data detach([[ARGA]] : memref<10xf32>)
688// CHECK: acc.exit_data copyout([[ARGA]] : memref<10xf32>) attributes {async}
689// CHECK: acc.exit_data delete([[ARGA]] : memref<10xf32>) attributes {wait}
690// CHECK: acc.exit_data async([[I64VALUE]] : i64) copyout([[ARGA]] : memref<10xf32>)
691// CHECK: acc.exit_data if([[IFCOND]]) copyout([[ARGA]] : memref<10xf32>)
692// CHECK: acc.exit_data wait_devnum([[I64VALUE]] : i64) wait([[I32VALUE]], [[IDXVALUE]] : i32, index) copyout([[ARGA]] : memref<10xf32>)
693// -----
694
695
696func @testenterdataop(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32>) -> () {
697  %ifCond = constant true
698  %i64Value = constant 1 : i64
699  %i32Value = constant 1 : i32
700  %idxValue = constant 1 : index
701
702  acc.enter_data copyin(%a : memref<10xf32>)
703  acc.enter_data create(%a : memref<10xf32>) create_zero(%b, %c : memref<10xf32>, memref<10x10xf32>)
704  acc.enter_data attach(%a : memref<10xf32>)
705  acc.enter_data copyin(%a : memref<10xf32>) attributes {async}
706  acc.enter_data create(%a : memref<10xf32>) attributes {wait}
707  acc.enter_data async(%i64Value : i64) copyin(%a : memref<10xf32>)
708  acc.enter_data if(%ifCond) copyin(%a : memref<10xf32>)
709  acc.enter_data wait_devnum(%i64Value: i64) wait(%i32Value, %idxValue : i32, index) copyin(%a : memref<10xf32>)
710
711  return
712}
713
714// CHECK: func @testenterdataop([[ARGA:%.*]]: memref<10xf32>, [[ARGB:%.*]]: memref<10xf32>, [[ARGC:%.*]]: memref<10x10xf32>) {
715// CHECK: [[IFCOND1:%.*]] = constant true
716// CHECK: [[I64VALUE:%.*]] = constant 1 : i64
717// CHECK: [[I32VALUE:%.*]] = constant 1 : i32
718// CHECK: [[IDXVALUE:%.*]] = constant 1 : index
719// CHECK: acc.enter_data copyin([[ARGA]] : memref<10xf32>)
720// CHECK: acc.enter_data create([[ARGA]] : memref<10xf32>) create_zero([[ARGB]], [[ARGC]] : memref<10xf32>, memref<10x10xf32>)
721// CHECK: acc.enter_data attach([[ARGA]] : memref<10xf32>)
722// CHECK: acc.enter_data copyin([[ARGA]] : memref<10xf32>) attributes {async}
723// CHECK: acc.enter_data create([[ARGA]] : memref<10xf32>) attributes {wait}
724// CHECK: acc.enter_data async([[I64VALUE]] : i64) copyin([[ARGA]] : memref<10xf32>)
725// CHECK: acc.enter_data if([[IFCOND]]) copyin([[ARGA]] : memref<10xf32>)
726// CHECK: acc.enter_data wait_devnum([[I64VALUE]] : i64) wait([[I32VALUE]], [[IDXVALUE]] : i32, index) copyin([[ARGA]] : memref<10xf32>)
727