xref: /llvm-project/mlir/test/Dialect/OpenACC/invalid.mlir (revision a63f915771ea89651a53584e483b3c5d9e73bd27)
1// RUN: mlir-opt -split-input-file -verify-diagnostics %s
2
3%1 = arith.constant 1 : i32
4%2 = arith.constant 10 : i32
5// expected-error@+1 {{gang, worker or vector cannot appear with the seq attr}}
6acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {
7  "test.openacc_dummy_op"() : () -> ()
8  acc.yield
9} attributes {seq = [#acc.device_type<none>], gang = [#acc.device_type<none>]}
10
11// -----
12
13%1 = arith.constant 1 : i32
14%2 = arith.constant 10 : i32
15// expected-error@+1 {{gang, worker or vector cannot appear with the seq attr}}
16acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {
17  "test.openacc_dummy_op"() : () -> ()
18  acc.yield
19} attributes {seq = [#acc.device_type<none>], worker = [#acc.device_type<none>]}
20
21// -----
22
23%1 = arith.constant 1 : i32
24%2 = arith.constant 10 : i32
25// expected-error@+1 {{gang, worker or vector cannot appear with the seq attr}}
26acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {
27  "test.openacc_dummy_op"() : () -> ()
28  acc.yield
29} attributes {seq = [#acc.device_type<none>], vector = [#acc.device_type<none>]}
30
31// -----
32
33%1 = arith.constant 1 : i32
34%2 = arith.constant 10 : i32
35// expected-error@+1 {{gang, worker or vector cannot appear with the seq attr}}
36acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {
37  "test.openacc_dummy_op"() : () -> ()
38  acc.yield
39} attributes {seq = [#acc.device_type<none>], worker = [#acc.device_type<none>], gang = [#acc.device_type<none>]}
40
41// -----
42
43%1 = arith.constant 1 : i32
44%2 = arith.constant 10 : i32
45// expected-error@+1 {{gang, worker or vector cannot appear with the seq attr}}
46acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {
47  "test.openacc_dummy_op"() : () -> ()
48  acc.yield
49} attributes {seq = [#acc.device_type<none>], vector = [#acc.device_type<none>], gang = [#acc.device_type<none>]}
50
51// -----
52
53%1 = arith.constant 1 : i32
54%2 = arith.constant 10 : i32
55// expected-error@+1 {{gang, worker or vector cannot appear with the seq attr}}
56acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {
57  "test.openacc_dummy_op"() : () -> ()
58  acc.yield
59} attributes {seq = [#acc.device_type<none>], vector = [#acc.device_type<none>], worker = [#acc.device_type<none>]}
60
61// -----
62
63%1 = arith.constant 1 : i32
64%2 = arith.constant 10 : i32
65// expected-error@+1 {{gang, worker or vector cannot appear with the seq attr}}
66acc.loop {
67  "test.openacc_dummy_op"() : () -> ()
68  acc.yield
69} attributes {seq = [#acc.device_type<none>], vector = [#acc.device_type<none>], worker = [#acc.device_type<none>], gang = [#acc.device_type<none>]}
70
71// -----
72
73// expected-error@+1 {{expected non-empty body.}}
74acc.loop {
75}
76
77// -----
78
79// expected-error@+1 {{'acc.loop' op duplicate device_type found in gang attribute}}
80acc.loop {
81  acc.yield
82} attributes {gang = [#acc.device_type<none>, #acc.device_type<none>]}
83
84// -----
85
86// expected-error@+1 {{'acc.loop' op duplicate device_type found in worker attribute}}
87acc.loop {
88  acc.yield
89} attributes {worker = [#acc.device_type<none>, #acc.device_type<none>]}
90
91// -----
92
93// expected-error@+1 {{'acc.loop' op duplicate device_type found in vector attribute}}
94acc.loop {
95  acc.yield
96} attributes {vector = [#acc.device_type<none>, #acc.device_type<none>]}
97
98// -----
99
100%1 = arith.constant 1 : i32
101%2 = arith.constant 10 : i32
102// expected-error@+1 {{only one of "auto", "independent", "seq" can be present at the same time}}
103acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {
104  acc.yield
105} attributes {auto_ = [#acc.device_type<none>], seq = [#acc.device_type<none>], inclusiveUpperbound = array<i1: true>}
106
107// -----
108
109// expected-error@+1 {{at least one operand or the default attribute must appear on the data operation}}
110acc.data {
111  acc.yield
112}
113
114// -----
115
116%value = memref.alloc() : memref<10xf32>
117// expected-error@+1 {{expect data entry/exit operation or acc.getdeviceptr as defining op}}
118acc.data dataOperands(%value : memref<10xf32>) {
119  acc.yield
120}
121
122// -----
123
124// expected-error@+1 {{at least one value must be present in dataOperands}}
125acc.update
126
127// -----
128
129%cst = arith.constant 1 : index
130%value = memref.alloc() : memref<f32>
131%0 = acc.update_device varPtr(%value : memref<f32>) -> memref<f32>
132// expected-error@+1 {{async attribute cannot appear with asyncOperand}}
133acc.update async(%cst: index) dataOperands(%0 : memref<f32>) attributes {async = [#acc.device_type<none>]}
134
135// -----
136
137%cst = arith.constant 1 : index
138%value = memref.alloc() : memref<f32>
139%0 = acc.update_device varPtr(%value : memref<f32>) -> memref<f32>
140// expected-error@+1 {{wait attribute cannot appear with waitOperands}}
141acc.update wait({%cst: index}) dataOperands(%0: memref<f32>) attributes {waitOnly = [#acc.device_type<none>]}
142
143// -----
144
145%cst = arith.constant 1 : index
146// expected-error@+1 {{wait_devnum cannot appear without waitOperands}}
147acc.wait wait_devnum(%cst: index)
148
149// -----
150
151%cst = arith.constant 1 : index
152// expected-error@+1 {{async attribute cannot appear with asyncOperand}}
153acc.wait async(%cst: index) attributes {async}
154
155// -----
156
157acc.parallel {
158// expected-error@+1 {{'acc.init' op cannot be nested in a compute operation}}
159  acc.init
160  acc.yield
161}
162
163// -----
164
165%1 = arith.constant 1 : i32
166%2 = arith.constant 10 : i32
167acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32){
168// expected-error@+1 {{'acc.init' op cannot be nested in a compute operation}}
169  acc.init
170  acc.yield
171} attributes {inclusiveUpperbound = array<i1: true>}
172
173// -----
174
175acc.parallel {
176// expected-error@+1 {{'acc.shutdown' op cannot be nested in a compute operation}}
177  acc.shutdown
178  acc.yield
179}
180
181// -----
182
183%1 = arith.constant 1 : i32
184%2 = arith.constant 10 : i32
185acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {
186// expected-error@+1 {{'acc.shutdown' op cannot be nested in a compute operation}}
187  acc.shutdown
188  acc.yield
189} attributes {inclusiveUpperbound = array<i1: true>}
190
191// -----
192
193%1 = arith.constant 1 : i32
194%2 = arith.constant 10 : i32
195acc.loop control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {
196  "test.openacc_dummy_op"() ({
197    // expected-error@+1 {{'acc.shutdown' op cannot be nested in a compute operation}}
198    acc.shutdown
199  }) : () -> ()
200  acc.yield
201} attributes {inclusiveUpperbound = array<i1: true>}
202
203// -----
204
205// expected-error@+1 {{at least one operand must be present in dataOperands on the exit data operation}}
206acc.exit_data attributes {async}
207
208// -----
209
210%cst = arith.constant 1 : index
211%value = memref.alloc() : memref<f32>
212%0 = acc.getdeviceptr varPtr(%value : memref<f32>) -> memref<f32>
213// expected-error@+1 {{async attribute cannot appear with asyncOperand}}
214acc.exit_data async(%cst: index) dataOperands(%0 : memref<f32>) attributes {async}
215acc.delete accPtr(%0 : memref<f32>)
216
217// -----
218
219%cst = arith.constant 1 : index
220%value = memref.alloc() : memref<f32>
221%0 = acc.getdeviceptr varPtr(%value : memref<f32>) -> memref<f32>
222// expected-error@+1 {{wait_devnum cannot appear without waitOperands}}
223acc.exit_data wait_devnum(%cst: index) dataOperands(%0 : memref<f32>)
224acc.delete accPtr(%0 : memref<f32>)
225
226// -----
227
228// expected-error@+1 {{at least one operand must be present in dataOperands on the enter data operation}}
229acc.enter_data attributes {async}
230
231// -----
232
233%cst = arith.constant 1 : index
234%value = memref.alloc() : memref<f32>
235%0 = acc.create varPtr(%value : memref<f32>) -> memref<f32>
236// expected-error@+1 {{async attribute cannot appear with asyncOperand}}
237acc.enter_data async(%cst: index) dataOperands(%0 : memref<f32>) attributes {async}
238
239// -----
240
241%cst = arith.constant 1 : index
242%value = memref.alloc() : memref<f32>
243%0 = acc.create varPtr(%value : memref<f32>) -> memref<f32>
244// expected-error@+1 {{wait attribute cannot appear with waitOperands}}
245acc.enter_data wait(%cst: index) dataOperands(%0 : memref<f32>) attributes {wait}
246
247// -----
248
249%cst = arith.constant 1 : index
250%value = memref.alloc() : memref<f32>
251%0 = acc.create varPtr(%value : memref<f32>) -> memref<f32>
252// expected-error@+1 {{wait_devnum cannot appear without waitOperands}}
253acc.enter_data wait_devnum(%cst: index) dataOperands(%0 : memref<f32>)
254
255// -----
256
257%value = memref.alloc() : memref<10xf32>
258// expected-error@+1 {{expect data entry operation as defining op}}
259acc.enter_data dataOperands(%value : memref<10xf32>)
260
261// -----
262
263%0 = arith.constant 1.0 : f32
264// expected-error@+1 {{operand #0 must be integer or index, but got 'f32'}}
265%1 = acc.bounds lowerbound(%0 : f32)
266
267// -----
268
269%value = memref.alloc() : memref<10xf32>
270// expected-error@+1 {{expect data entry/exit operation or acc.getdeviceptr as defining op}}
271acc.update dataOperands(%value : memref<10xf32>)
272
273// -----
274
275%value = memref.alloc() : memref<10xf32>
276// expected-error@+1 {{expect data entry/exit operation or acc.getdeviceptr as defining op}}
277acc.parallel dataOperands(%value : memref<10xf32>) {
278  acc.yield
279}
280
281// -----
282
283%value = memref.alloc() : memref<10xf32>
284// expected-error@+1 {{expect data entry/exit operation or acc.getdeviceptr as defining op}}
285acc.serial dataOperands(%value : memref<10xf32>) {
286  acc.yield
287}
288
289// -----
290
291%value = memref.alloc() : memref<10xf32>
292// expected-error@+1 {{expect data entry/exit operation or acc.getdeviceptr as defining op}}
293acc.kernels dataOperands(%value : memref<10xf32>) {
294  acc.yield
295}
296
297// -----
298
299// expected-error@+1 {{expects non-empty init region}}
300acc.private.recipe @privatization_i32 : !llvm.ptr init {
301}
302
303// -----
304
305// expected-error@+1 {{expects init region first argument of the privatization type}}
306acc.private.recipe @privatization_i32 : !llvm.ptr init {
307^bb0(%arg0 : i32):
308  %c1 = arith.constant 1 : i32
309  %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr
310  acc.yield %0 : !llvm.ptr
311}
312
313// -----
314
315// expected-error@+1 {{expects destroy region first argument of the privatization type}}
316acc.private.recipe @privatization_i32 : !llvm.ptr init {
317^bb0(%arg0 : !llvm.ptr):
318  %c1 = arith.constant 1 : i32
319  %c0 = arith.constant 0 : i32
320  %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr
321  llvm.store %c0, %0 : i32, !llvm.ptr
322  acc.yield %0 : !llvm.ptr
323} destroy {
324^bb0(%arg0 : f32):
325  "test.openacc_dummy_op"(%arg0) : (f32) -> ()
326}
327
328// -----
329
330// expected-error@+1 {{expects non-empty init region}}
331acc.firstprivate.recipe @privatization_i32 : !llvm.ptr init {
332} copy {}
333
334// -----
335
336// expected-error@+1 {{expects init region first argument of the privatization type}}
337acc.firstprivate.recipe @privatization_i32 : !llvm.ptr init {
338^bb0(%arg0 : i32):
339  %c1 = arith.constant 1 : i32
340  %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr
341  acc.yield %0 : !llvm.ptr
342} copy {}
343
344// -----
345
346// expected-error@+1 {{expects non-empty copy region}}
347acc.firstprivate.recipe @privatization_i32 : !llvm.ptr init {
348^bb0(%arg0 : !llvm.ptr):
349  %c1 = arith.constant 1 : i32
350  %c0 = arith.constant 0 : i32
351  %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr
352  llvm.store %c0, %0 : i32, !llvm.ptr
353  acc.yield %0 : !llvm.ptr
354} copy {
355}
356
357// -----
358
359// expected-error@+1 {{expects copy region with two arguments of the privatization type}}
360acc.firstprivate.recipe @privatization_i32 : !llvm.ptr init {
361^bb0(%arg0 : !llvm.ptr):
362  %c1 = arith.constant 1 : i32
363  %c0 = arith.constant 0 : i32
364  %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr
365  llvm.store %c0, %0 : i32, !llvm.ptr
366  acc.yield %0 : !llvm.ptr
367} copy {
368^bb0(%arg0 : f32):
369  "test.openacc_dummy_op"(%arg0) : (f32) -> ()
370}
371
372// -----
373
374// expected-error@+1 {{expects copy region with two arguments of the privatization type}}
375acc.firstprivate.recipe @privatization_i32 : !llvm.ptr init {
376^bb0(%arg0 : !llvm.ptr):
377  %c1 = arith.constant 1 : i32
378  %c0 = arith.constant 0 : i32
379  %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr
380  llvm.store %c0, %0 : i32, !llvm.ptr
381  acc.yield %0 : !llvm.ptr
382} copy {
383^bb0(%arg0 : f32, %arg1 : i32):
384  "test.openacc_dummy_op"(%arg0) : (f32) -> ()
385}
386
387// -----
388
389// expected-error@+1 {{expects destroy region first argument of the privatization type}}
390acc.firstprivate.recipe @privatization_i32 : i32 init {
391^bb0(%arg0 : i32):
392  %0 = arith.constant 1 : i32
393  acc.yield %0 : i32
394} copy {
395^bb0(%arg0 : i32, %arg1 : !llvm.ptr):
396  llvm.store %arg0, %arg1 : i32, !llvm.ptr
397  acc.yield
398} destroy {
399^bb0(%arg0 : f32):
400  acc.yield
401}
402
403// -----
404
405%1 = arith.constant 1 : i32
406%2 = arith.constant 10 : i32
407// expected-error@+1 {{expected ')'}}
408acc.loop gang({static=%i64Value: i64, num=%i64Value: i64} control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {
409  "test.openacc_dummy_op"() : () -> ()
410  acc.yield
411}
412
413// -----
414
415// expected-error@+1 {{expects non-empty init region}}
416acc.reduction.recipe @reduction_i64 : i64 reduction_operator<add> init {
417} combiner {}
418
419// -----
420
421// expected-error@+1 {{expects init region first argument of the reduction type}}
422acc.reduction.recipe @reduction_i64 : i64 reduction_operator<add> init {
423^bb0(%0: i32):
424  %1 = arith.constant 0 : i64
425  acc.yield %1 : i64
426} combiner {}
427
428// -----
429
430// expected-error@+1 {{expects non-empty combiner region}}
431acc.reduction.recipe @reduction_i64 : i64 reduction_operator<add> init {
432^bb0(%0: i64):
433  %1 = arith.constant 0 : i64
434  acc.yield %1 : i64
435} combiner {}
436
437// -----
438
439// expected-error@+1 {{expects combiner region with the first two arguments of the reduction type}}
440acc.reduction.recipe @reduction_i64 : i64 reduction_operator<add> init {
441^bb0(%0: i64):
442  %1 = arith.constant 0 : i64
443  acc.yield %1 : i64
444} combiner {
445^bb0(%0: i32):
446  acc.yield %0 : i32
447}
448
449// -----
450
451// expected-error@+1 {{expects combiner region with the first two arguments of the reduction type}}
452acc.reduction.recipe @reduction_i64 : i64 reduction_operator<add> init {
453^bb0(%0: i64):
454  %1 = arith.constant 0 : i64
455  acc.yield %1 : i64
456} combiner {
457^bb0(%0: i64):
458  acc.yield %0 : i64
459}
460
461// -----
462
463// expected-error@+1 {{expects combiner region to yield a value of the reduction type}}
464acc.reduction.recipe @reduction_i64 : i64 reduction_operator<add> init {
465^bb0(%0: i64):
466  %1 = arith.constant 0 : i64
467  acc.yield %1 : i64
468} combiner {
469^bb0(%0: i64, %1: i64):
470  %2 = arith.constant 0 : i32
471  acc.yield %2 : i32
472}
473
474// -----
475
476%1 = arith.constant 1 : i32
477%2 = arith.constant 10 : i32
478// expected-error@+1 {{new value expected after comma}}
479acc.loop gang({static=%i64Value: i64, ) control(%iv : i32) = (%1 : i32) to (%2 : i32) step (%1 : i32) {
480  "test.openacc_dummy_op"() : () -> ()
481  acc.yield
482}
483
484// -----
485
486func.func @fct1(%0 : !llvm.ptr) -> () {
487  // expected-error@+1 {{expected symbol reference @privatization_i32 to point to a private declaration}}
488  acc.serial private(@privatization_i32 -> %0 : !llvm.ptr) {
489  }
490  return
491}
492
493// -----
494
495// expected-error@+1 {{expect at least one of num, dim or static values}}
496acc.loop gang({}) {
497  "test.openacc_dummy_op"() : () -> ()
498  acc.yield
499}
500
501// -----
502
503%i64value = arith.constant 1 : i64
504// expected-error@+1 {{num_gangs expects a maximum of 3 values per segment}}
505acc.parallel num_gangs({%i64value: i64, %i64value : i64, %i64value : i64, %i64value : i64}) {
506}
507
508// -----
509
510%0 = "arith.constant"() <{value = 1 : i64}> : () -> i64
511// expected-error@+1 {{num_gangs operand count does not match count in segments}}
512"acc.parallel"(%0) <{numGangsSegments = array<i32: 1>, operandSegmentSizes = array<i32: 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0>}> ({
513}) : (i64) -> ()
514
515// -----
516
517%i64value = arith.constant 1 : i64
518acc.parallel {
519// expected-error@+1 {{'acc.set' op cannot be nested in a compute operation}}
520  acc.set attributes {device_type = #acc.device_type<nvidia>}
521  acc.yield
522}
523
524// -----
525
526// expected-error@+1 {{'acc.set' op at least one default_async, device_num, or device_type operand must appear}}
527acc.set
528
529// -----
530
531func.func @acc_atomic_write(%addr : memref<memref<i32>>, %val : i32) {
532  // expected-error @below {{address must dereference to value type}}
533  acc.atomic.write %addr = %val : memref<memref<i32>>, i32
534  return
535}
536
537// -----
538
539func.func @acc_atomic_update(%x: memref<i32>, %expr: f32) {
540  // expected-error @below {{the type of the operand must be a pointer type whose element type is the same as that of the region argument}}
541  acc.atomic.update %x : memref<i32> {
542  ^bb0(%xval: f32):
543    %newval = llvm.fadd %xval, %expr : f32
544    acc.yield %newval : f32
545  }
546  return
547}
548
549// -----
550
551func.func @acc_atomic_update(%x: memref<i32>, %expr: i32) {
552  // expected-error @+2 {{op expects regions to end with 'acc.yield', found 'acc.terminator'}}
553  // expected-note @below {{in custom textual format, the absence of terminator implies 'acc.yield'}}
554  acc.atomic.update %x : memref<i32> {
555  ^bb0(%xval: i32):
556    %newval = llvm.add %xval, %expr : i32
557    acc.terminator
558  }
559  return
560}
561// -----
562
563func.func @acc_atomic_update(%x: memref<i32>, %expr: i32) {
564  // expected-error @below {{invalid kind of type specified}}
565  acc.atomic.update %x : i32 {
566  ^bb0(%xval: i32):
567    %newval = llvm.add %xval, %expr : i32
568    acc.yield %newval : i32
569  }
570  return
571}
572
573// -----
574
575func.func @acc_atomic_update(%x: memref<i32>, %expr: i32) {
576  // expected-error @below {{only updated value must be returned}}
577  acc.atomic.update %x : memref<i32> {
578  ^bb0(%xval: i32):
579    %newval = llvm.add %xval, %expr : i32
580    acc.yield %newval, %expr : i32, i32
581  }
582  return
583}
584
585// -----
586
587func.func @acc_atomic_update(%x: memref<i32>, %expr: i32, %y: f32) {
588  // expected-error @below {{input and yielded value must have the same type}}
589  acc.atomic.update %x : memref<i32> {
590  ^bb0(%xval: i32):
591    %newval = llvm.add %xval, %expr : i32
592    acc.yield %y: f32
593  }
594  return
595}
596
597// -----
598
599func.func @acc_atomic_update(%x: memref<i32>, %expr: i32) {
600  // expected-error @below {{the region must accept exactly one argument}}
601  acc.atomic.update %x : memref<i32> {
602  ^bb0(%xval: i32, %tmp: i32):
603    %newval = llvm.add %xval, %expr : i32
604    acc.yield %newval : i32
605  }
606  return
607}
608
609// -----
610
611func.func @acc_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
612  // expected-error @below {{expected three operations in atomic.capture region}}
613  acc.atomic.capture {
614    acc.atomic.read %v = %x : memref<i32>, memref<i32>, i32
615    acc.terminator
616  }
617  return
618}
619
620// -----
621
622func.func @acc_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
623  acc.atomic.capture {
624    // expected-error @below {{invalid sequence of operations in the capture region}}
625    acc.atomic.read %v = %x : memref<i32>, memref<i32>, i32
626    acc.atomic.read %v = %x : memref<i32>, memref<i32>, i32
627    acc.terminator
628  }
629  return
630}
631
632// -----
633
634func.func @acc_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
635  acc.atomic.capture {
636    // expected-error @below {{invalid sequence of operations in the capture region}}
637    acc.atomic.update %x : memref<i32> {
638    ^bb0(%xval: i32):
639      %newval = llvm.add %xval, %expr : i32
640      acc.yield %newval : i32
641    }
642    acc.atomic.update %x : memref<i32> {
643    ^bb0(%xval: i32):
644      %newval = llvm.add %xval, %expr : i32
645      acc.yield %newval : i32
646    }
647    acc.terminator
648  }
649  return
650}
651
652// -----
653
654func.func @acc_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
655  acc.atomic.capture {
656    // expected-error @below {{invalid sequence of operations in the capture region}}
657    acc.atomic.write %x = %expr : memref<i32>, i32
658    acc.atomic.write %x = %expr : memref<i32>, i32
659    acc.terminator
660  }
661  return
662}
663
664// -----
665
666func.func @acc_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
667  acc.atomic.capture {
668    // expected-error @below {{invalid sequence of operations in the capture region}}
669    acc.atomic.write %x = %expr : memref<i32>, i32
670    acc.atomic.update %x : memref<i32> {
671    ^bb0(%xval: i32):
672      %newval = llvm.add %xval, %expr : i32
673      acc.yield %newval : i32
674    }
675    acc.terminator
676  }
677  return
678}
679
680// -----
681
682func.func @acc_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
683  acc.atomic.capture {
684    // expected-error @below {{invalid sequence of operations in the capture region}}
685    acc.atomic.update %x : memref<i32> {
686    ^bb0(%xval: i32):
687      %newval = llvm.add %xval, %expr : i32
688      acc.yield %newval : i32
689    }
690    acc.atomic.write %x = %expr : memref<i32>, i32
691    acc.terminator
692  }
693  return
694}
695
696// -----
697
698func.func @acc_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
699  acc.atomic.capture {
700    // expected-error @below {{invalid sequence of operations in the capture region}}
701    acc.atomic.write %x = %expr : memref<i32>, i32
702    acc.atomic.read %v = %x : memref<i32>, memref<i32>, i32
703    acc.terminator
704  }
705  return
706}
707
708// -----
709
710func.func @acc_atomic_capture(%x: memref<i32>, %y: memref<i32>, %v: memref<i32>, %expr: i32) {
711  acc.atomic.capture {
712    // expected-error @below {{updated variable in atomic.update must be captured in second operation}}
713    acc.atomic.update %x : memref<i32> {
714    ^bb0(%xval: i32):
715      %newval = llvm.add %xval, %expr : i32
716      acc.yield %newval : i32
717    }
718    acc.atomic.read %v = %y : memref<i32>, memref<i32>, i32
719    acc.terminator
720  }
721}
722
723// -----
724
725func.func @acc_atomic_capture(%x: memref<i32>, %y: memref<i32>, %v: memref<i32>, %expr: i32) {
726  acc.atomic.capture {
727    // expected-error @below {{captured variable in atomic.read must be updated in second operation}}
728    acc.atomic.read %v = %y : memref<i32>, memref<i32>, i32
729    acc.atomic.update %x : memref<i32> {
730    ^bb0(%xval: i32):
731      %newval = llvm.add %xval, %expr : i32
732      acc.yield %newval : i32
733    }
734    acc.terminator
735  }
736}
737
738// -----
739
740func.func @acc_atomic_capture(%x: memref<i32>, %y: memref<i32>, %v: memref<i32>, %expr: i32) {
741  acc.atomic.capture {
742    // expected-error @below {{captured variable in atomic.read must be updated in second operation}}
743    acc.atomic.read %v = %x : memref<i32>, memref<i32>, i32
744    acc.atomic.write %y = %expr : memref<i32>, i32
745    acc.terminator
746  }
747}
748
749// -----
750
751func.func @acc_combined() {
752  // expected-error @below {{expected 'loop'}}
753  acc.parallel combined() {
754  }
755
756  return
757}
758
759// -----
760
761func.func @acc_combined() {
762  // expected-error @below {{expected compute construct name}}
763  acc.loop combined(loop) {
764  }
765
766  return
767}
768
769// -----
770
771func.func @acc_combined() {
772  // expected-error @below {{expected 'loop'}}
773  acc.parallel combined(parallel loop) {
774  }
775
776  return
777}
778
779// -----
780
781func.func @acc_combined() {
782  // expected-error @below {{expected ')'}}
783  acc.loop combined(parallel loop) {
784  }
785
786  return
787}
788