xref: /llvm-project/mlir/test/IR/traits.mlir (revision 8955e285e1ac48bfcd9e030a055e66aec37785cc)
1// RUN: mlir-opt -allow-unregistered-dialect %s -split-input-file -verify-diagnostics | FileCheck %s
2
3// CHECK: succeededSameOperandsElementType
4func.func @succeededSameOperandsElementType(%t10x10 : tensor<10x10xf32>, %t1f: tensor<1xf32>, %v1: vector<1xf32>, %t1i: tensor<1xi32>, %sf: f32) {
5  "test.same_operand_element_type"(%t1f, %t1f) : (tensor<1xf32>, tensor<1xf32>) -> tensor<1xi32>
6  "test.same_operand_element_type"(%t1f, %t10x10) : (tensor<1xf32>, tensor<10x10xf32>) -> tensor<1xi32>
7  "test.same_operand_element_type"(%t10x10, %v1) : (tensor<10x10xf32>, vector<1xf32>) -> tensor<1xi32>
8  "test.same_operand_element_type"(%v1, %t1f) : (vector<1xf32>, tensor<1xf32>) -> tensor<1xi32>
9  "test.same_operand_element_type"(%v1, %t1f) : (vector<1xf32>, tensor<1xf32>) -> tensor<121xi32>
10  "test.same_operand_element_type"(%sf, %sf) : (f32, f32) -> i32
11  "test.same_operand_element_type"(%sf, %t1f) : (f32, tensor<1xf32>) -> tensor<121xi32>
12  "test.same_operand_element_type"(%sf, %v1) : (f32, vector<1xf32>) -> tensor<121xi32>
13  "test.same_operand_element_type"(%sf, %t10x10) : (f32, tensor<10x10xf32>) -> tensor<121xi32>
14  return
15}
16
17// -----
18
19func.func @failedSameOperandElementType(%t1f: tensor<1xf32>, %t1i: tensor<1xi32>) {
20  // expected-error@+1 {{requires the same element type for all operands}}
21  "test.same_operand_element_type"(%t1f, %t1i) : (tensor<1xf32>, tensor<1xi32>) -> tensor<1xf32>
22}
23
24// -----
25
26func.func @failedSameOperandAndResultElementType_no_operands() {
27  // expected-error@+1 {{expected 2 operands, but found 0}}
28  "test.same_operand_element_type"() : () -> tensor<1xf32>
29}
30
31// -----
32
33func.func @failedSameOperandElementType_scalar_type_mismatch(%si: i32, %sf: f32) {
34  // expected-error@+1 {{requires the same element type for all operands}}
35  "test.same_operand_element_type"(%sf, %si) : (f32, i32) -> tensor<1xf32>
36}
37
38// -----
39
40// CHECK: succeededSameOperandAndResultElementType
41func.func @succeededSameOperandAndResultElementType(%t10x10 : tensor<10x10xf32>, %t1f: tensor<1xf32>, %v1: vector<1xf32>, %t1i: tensor<1xi32>, %sf: f32) {
42  "test.same_operand_and_result_element_type"(%t1f, %t1f) : (tensor<1xf32>, tensor<1xf32>) -> tensor<1xf32>
43  "test.same_operand_and_result_element_type"(%t1f, %t10x10) : (tensor<1xf32>, tensor<10x10xf32>) -> tensor<1xf32>
44  "test.same_operand_and_result_element_type"(%t10x10, %v1) : (tensor<10x10xf32>, vector<1xf32>) -> tensor<1xf32>
45  "test.same_operand_and_result_element_type"(%v1, %t1f) : (vector<1xf32>, tensor<1xf32>) -> tensor<1xf32>
46  "test.same_operand_and_result_element_type"(%v1, %t1f) : (vector<1xf32>, tensor<1xf32>) -> tensor<121xf32>
47  "test.same_operand_and_result_element_type"(%sf, %sf) : (f32, f32) -> f32
48  "test.same_operand_and_result_element_type"(%sf, %t1f) : (f32, tensor<1xf32>) -> tensor<121xf32>
49  "test.same_operand_and_result_element_type"(%sf, %v1) : (f32, vector<1xf32>) -> tensor<121xf32>
50  "test.same_operand_and_result_element_type"(%sf, %t10x10) : (f32, tensor<10x10xf32>) -> tensor<121xf32>
51  return
52}
53
54// -----
55
56func.func @failedSameOperandAndResultElementType_operand_result_mismatch(%t1f: tensor<1xf32>) {
57  // expected-error@+1 {{requires the same element type for all operands and results}}
58  "test.same_operand_and_result_element_type"(%t1f, %t1f) : (tensor<1xf32>, tensor<1xf32>) -> tensor<1xi32>
59}
60
61// -----
62
63func.func @failedSameOperandAndResultElementType_operand_mismatch(%t1f: tensor<1xf32>, %t1i: tensor<1xi32>) {
64  // expected-error@+1 {{requires the same element type for all operands and results}}
65  "test.same_operand_and_result_element_type"(%t1f, %t1i) : (tensor<1xf32>, tensor<1xi32>) -> tensor<1xf32>
66}
67
68// -----
69
70func.func @failedSameOperandAndResultElementType_result_mismatch(%t1f: tensor<1xf32>) {
71  // expected-error@+1 {{requires the same element type for all operands and results}}
72  %0:2 = "test.same_operand_and_result_element_type"(%t1f) : (tensor<1xf32>) -> (tensor<1xf32>, tensor<1xi32>)
73}
74
75// -----
76
77func.func @failedSameOperandAndResultElementType_no_operands() {
78  // expected-error@+1 {{expected 1 or more operands}}
79  "test.same_operand_and_result_element_type"() : () -> tensor<1xf32>
80}
81
82// -----
83
84func.func @failedSameOperandAndResultElementType_no_results(%t1f: tensor<1xf32>) {
85  // expected-error@+1 {{expected 1 or more results}}
86  "test.same_operand_and_result_element_type"(%t1f) : (tensor<1xf32>) -> ()
87}
88
89// -----
90
91// CHECK: succeededSameOperandShape
92func.func @succeededSameOperandShape(%t10x10 : tensor<10x10xf32>, %t1: tensor<1xf32>, %m10x10 : memref<10x10xi32>, %tr: tensor<*xf32>) {
93  "test.same_operand_shape"(%t1, %t1) : (tensor<1xf32>, tensor<1xf32>) -> ()
94  "test.same_operand_shape"(%t10x10, %t10x10) : (tensor<10x10xf32>, tensor<10x10xf32>) -> ()
95  "test.same_operand_shape"(%t1, %tr) : (tensor<1xf32>, tensor<*xf32>) -> ()
96  "test.same_operand_shape"(%t10x10, %m10x10) : (tensor<10x10xf32>, memref<10x10xi32>) -> ()
97  return
98}
99
100// -----
101
102func.func @failedSameOperandShape_operand_mismatch(%t10x10 : tensor<10x10xf32>, %t1: tensor<1xf32>) {
103  // expected-error@+1 {{requires the same shape for all operands}}
104  "test.same_operand_shape"(%t1, %t10x10) : (tensor<1xf32>, tensor<10x10xf32>) -> ()
105}
106
107// -----
108
109func.func @failedSameOperandShape_no_operands() {
110  // expected-error@+1 {{expected 1 or more operands}}
111  "test.same_operand_shape"() : () -> ()
112}
113
114// -----
115
116// CHECK: succeededSameOperandAndResultShape
117func.func @succeededSameOperandAndResultShape(%t10x10 : tensor<10x10xf32>, %t1: tensor<1xf32>, %tr: tensor<*xf32>, %t1d: tensor<?xf32>) {
118  "test.same_operand_and_result_shape"(%t1, %t1) : (tensor<1xf32>, tensor<1xf32>) -> tensor<1xf32>
119  "test.same_operand_and_result_shape"(%t10x10, %t10x10) : (tensor<10x10xf32>, tensor<10x10xf32>) -> tensor<10x10xf32>
120  "test.same_operand_and_result_shape"(%t1, %tr) : (tensor<1xf32>, tensor<*xf32>) -> tensor<1xf32>
121  "test.same_operand_and_result_shape"(%t1, %t1d) : (tensor<1xf32>, tensor<?xf32>) -> tensor<1xf32>
122  "test.same_operand_and_result_shape"(%t1, %t1d) : (tensor<1xf32>, tensor<?xf32>) -> memref<1xf32>
123
124  return
125}
126
127// -----
128
129func.func @failedSameOperandAndResultShape_operand_result_mismatch(%t10x10 : tensor<10x10xf32>, %t1: tensor<1xf32>) {
130  // expected-error@+1 {{requires the same shape for all operands and results}}
131  "test.same_operand_and_result_shape"(%t1, %t10x10) : (tensor<1xf32>, tensor<10x10xf32>) -> tensor<10x10xf32>
132}
133
134// -----
135
136func.func @failedSameOperandAndResultShape_operand_result_mismatch(%t10 : tensor<10xf32>, %t1: tensor<?xf32>) {
137  // expected-error@+1 {{requires the same shape for all operands and results}}
138  "test.same_operand_and_result_shape"(%t1, %t10) : (tensor<?xf32>, tensor<10xf32>) -> tensor<3xf32>
139}
140
141// -----
142
143func.func @failedSameOperandAndResultShape_no_operands() {
144  // expected-error@+1 {{expected 1 or more operands}}
145  "test.same_operand_and_result_shape"() : () -> (tensor<1xf32>)
146}
147
148// -----
149
150func.func @failedSameOperandAndResultShape_no_operands(%t1: tensor<1xf32>) {
151  // expected-error@+1 {{expected 1 or more results}}
152  "test.same_operand_and_result_shape"(%t1) : (tensor<1xf32>) -> ()
153}
154
155// -----
156
157// CHECK: succeededSameOperandAndResultType
158func.func @succeededSameOperandAndResultType(%t10x10 : tensor<10x10xf32>, %t1: tensor<1xf32>, %tr: tensor<*xf32>, %t1d: tensor<?xf32>, %i32 : i32) {
159  "test.same_operand_and_result_type"(%t1, %t1) : (tensor<1xf32>, tensor<1xf32>) -> tensor<1xf32>
160  "test.same_operand_and_result_type"(%t10x10, %t10x10) : (tensor<10x10xf32>, tensor<10x10xf32>) -> tensor<10x10xf32>
161  "test.same_operand_and_result_type"(%t1, %tr) : (tensor<1xf32>, tensor<*xf32>) -> tensor<1xf32>
162  "test.same_operand_and_result_type"(%t1, %t1d) : (tensor<1xf32>, tensor<?xf32>) -> tensor<1xf32>
163  "test.same_operand_and_result_type"(%i32, %i32) : (i32, i32) -> i32
164  return
165}
166
167// -----
168
169func.func @failedSameOperandAndResultType_operand_result_mismatch(%t10 : tensor<10xf32>, %t20 : tensor<20xf32>) {
170  // expected-error@+1 {{requires the same type for all operands and results}}
171  "test.same_operand_and_result_type"(%t10, %t20) : (tensor<10xf32>, tensor<20xf32>) -> tensor<10xf32>
172  return
173}
174
175// -----
176
177func.func @failedSameOperandAndResultType_encoding_mismatch(%t10 : tensor<10xf32>, %t20 : tensor<10xf32>) {
178  // expected-error@+1 {{requires the same encoding for all operands and results}}
179  "test.same_operand_and_result_type"(%t10, %t20) : (tensor<10xf32>, tensor<10xf32>) -> tensor<10xf32, "enc">
180  return
181}
182
183// -----
184
185func.func @failedElementwiseMappable_different_rankedness(%arg0: tensor<?xf32>, %arg1: tensor<*xf32>) {
186  // expected-error@+1 {{all non-scalar operands/results must have the same shape and base type}}
187  %0 = "test.elementwise_mappable"(%arg0, %arg1) : (tensor<?xf32>, tensor<*xf32>) -> tensor<*xf32>
188  return
189}
190
191// -----
192
193func.func @failedElementwiseMappable_different_rank(%arg0: tensor<?xf32>, %arg1: tensor<?x?xf32>) {
194  // expected-error@+1 {{all non-scalar operands/results must have the same shape and base type}}
195  %0 = "test.elementwise_mappable"(%arg0, %arg1) : (tensor<?xf32>, tensor<?x?xf32>) -> tensor<?x?xf32>
196  return
197}
198
199// -----
200
201func.func @elementwiseMappable_dynamic_shapes(%arg0: tensor<?xf32>,
202    %arg1: tensor<5xf32>) {
203  %0 = "test.elementwise_mappable"(%arg0, %arg1) :
204      (tensor<?xf32>, tensor<5xf32>) -> tensor<?xf32>
205  return
206}
207
208// -----
209
210func.func @failedElementwiseMappable_different_base_type(%arg0: vector<2xf32>, %arg1: tensor<2xf32>) {
211  // expected-error@+1 {{all non-scalar operands/results must have the same shape and base type}}
212  %0 = "test.elementwise_mappable"(%arg0, %arg1) : (vector<2xf32>, tensor<2xf32>) -> tensor<2xf32>
213  return
214}
215
216// -----
217
218func.func @failedElementwiseMappable_non_scalar_output(%arg0: vector<2xf32>) {
219  // expected-error@+1 {{if an operand is non-scalar, then there must be at least one non-scalar result}}
220  %0 = "test.elementwise_mappable"(%arg0) : (vector<2xf32>) -> f32
221  return
222}
223
224// -----
225
226func.func @failedElementwiseMappable_non_scalar_result_all_scalar_input(%arg0: f32) {
227  // expected-error@+1 {{if a result is non-scalar, then at least one operand must be non-scalar}}
228  %0 = "test.elementwise_mappable"(%arg0) : (f32) -> tensor<f32>
229  return
230}
231
232// -----
233
234func.func @failedElementwiseMappable_mixed_scalar_non_scalar_results(%arg0: tensor<10xf32>) {
235  // expected-error@+1 {{if an operand is non-scalar, then all results must be non-scalar}}
236  %0, %1 = "test.elementwise_mappable"(%arg0) : (tensor<10xf32>) -> (f32, tensor<10xf32>)
237  return
238}
239
240// -----
241
242func.func @failedElementwiseMappable_zero_results(%arg0: tensor<10xf32>) {
243  // expected-error@+1 {{if an operand is non-scalar, then there must be at least one non-scalar result}}
244  "test.elementwise_mappable"(%arg0) : (tensor<10xf32>) -> ()
245  return
246}
247
248// -----
249
250func.func @failedElementwiseMappable_zero_operands() {
251  // expected-error@+1 {{if a result is non-scalar, then at least one operand must be non-scalar}}
252  "test.elementwise_mappable"() : () -> (tensor<6xf32>)
253  return
254}
255
256// -----
257
258func.func @succeededElementwiseMappable(%arg0: vector<2xf32>) {
259  // Check that varying element types are allowed.
260  // CHECK: test.elementwise_mappable
261  %0 = "test.elementwise_mappable"(%arg0) : (vector<2xf32>) -> vector<2xf16>
262  return
263}
264
265// -----
266
267func.func @failedHasParent_wrong_parent() {
268  "some.op"() ({
269   // expected-error@+1 {{'test.child' op expects parent op 'test.parent'}}
270    "test.child"() : () -> ()
271  }) : () -> ()
272}
273
274// -----
275
276// CHECK: succeededParentOneOf
277func.func @succeededParentOneOf() {
278  "test.parent"() ({
279    "test.child_with_parent_one_of"() : () -> ()
280    "test.finish"() : () -> ()
281   }) : () -> ()
282  return
283}
284
285// -----
286
287// CHECK: succeededParent1OneOf
288func.func @succeededParent1OneOf() {
289  "test.parent1"() ({
290    "test.child_with_parent_one_of"() : () -> ()
291    "test.finish"() : () -> ()
292   }) : () -> ()
293  return
294}
295
296// -----
297
298func.func @failedParentOneOf_wrong_parent1() {
299  "some.otherop"() ({
300    // expected-error@+1 {{'test.child_with_parent_one_of' op expects parent op to be one of 'test.parent, test.parent1'}}
301    "test.child_with_parent_one_of"() : () -> ()
302    "test.finish"() : () -> ()
303   }) : () -> ()
304}
305
306
307// -----
308
309func.func @failedSingleBlockImplicitTerminator_empty_block() {
310   // expected-error@+1 {{'test.SingleBlockImplicitTerminator' op expects a non-empty block}}
311  "test.SingleBlockImplicitTerminator"() ({
312  ^entry:
313  }) : () -> ()
314}
315
316// -----
317
318func.func @failedSingleBlockImplicitTerminator_too_many_blocks() {
319   // expected-error@+1 {{'test.SingleBlockImplicitTerminator' op expects region #0 to have 0 or 1 block}}
320  "test.SingleBlockImplicitTerminator"() ({
321  ^entry:
322    "test.finish" () : () -> ()
323  ^other:
324    "test.finish" () : () -> ()
325  }) : () -> ()
326}
327
328// -----
329
330func.func @failedSingleBlockImplicitTerminator_missing_terminator() {
331   // expected-error@+2 {{'test.SingleBlockImplicitTerminator' op expects regions to end with 'test.finish'}}
332   // expected-note@+1 {{in custom textual format, the absence of terminator implies 'test.finish'}}
333  "test.SingleBlockImplicitTerminator"() ({
334  ^entry:
335    "test.non_existent_op"() : () -> ()
336  }) : () -> ()
337}
338
339// -----
340
341// Test the invariants of operations with the Symbol Trait.
342
343// expected-error@+1 {{op requires attribute 'sym_name'}}
344"test.symbol"() {} : () -> ()
345
346// -----
347
348// expected-error@+1 {{invalid properties {sym_name = "foo_2", sym_visibility} for op test.symbol: Invalid attribute `sym_visibility` in property conversion: unit}}
349"test.symbol"() <{sym_name = "foo_2", sym_visibility}> : () -> ()
350
351// -----
352
353// expected-error@+1 {{visibility expected to be one of ["public", "private", "nested"]}}
354"test.symbol"() {sym_name = "foo_2", sym_visibility = "foo"} : () -> ()
355
356// -----
357
358"test.symbol"() {sym_name = "foo_3", sym_visibility = "nested"} : () -> ()
359"test.symbol"() {sym_name = "foo_4", sym_visibility = "private"} : () -> ()
360"test.symbol"() {sym_name = "foo_5", sym_visibility = "public"} : () -> ()
361"test.symbol"() {sym_name = "foo_6"} : () -> ()
362
363// -----
364
365// Test that operation with the SymbolTable Trait define a new symbol scope.
366"test.symbol_scope"() ({
367  func.func private @foo()
368  "test.finish" () : () -> ()
369}) : () -> ()
370func.func private @foo()
371
372// -----
373
374// Test that operation with the SymbolTable Trait fails with  too many blocks.
375// expected-error@+1 {{op expects region #0 to have 0 or 1 blocks}}
376"test.symbol_scope"() ({
377  ^entry:
378    "test.finish" () : () -> ()
379  ^other:
380    "test.finish" () : () -> ()
381}) : () -> ()
382
383// -----
384
385func.func @failedMissingOperandSizeAttr(%arg: i32) {
386  // expected-error @+1 {{op operand count (4) does not match with the total size (0) specified in attribute 'operandSegmentSizes'}}
387  "test.attr_sized_operands"(%arg, %arg, %arg, %arg) : (i32, i32, i32, i32) -> ()
388}
389
390// -----
391
392func.func @failedOperandSizeAttrWrongType(%arg: i32) {
393  // expected-error @+1 {{op operand count (4) does not match with the total size (0) specified in attribute 'operandSegmentSizes'}}
394  "test.attr_sized_operands"(%arg, %arg, %arg, %arg) {operandSegmentSizes = 10} : (i32, i32, i32, i32) -> ()
395}
396
397// -----
398
399func.func @failedOperandSizeAttrWrongElementType(%arg: i32) {
400  // expected-error @+1 {{op operand count (4) does not match with the total size (0) specified in attribute 'operandSegmentSizes'}}
401  "test.attr_sized_operands"(%arg, %arg, %arg, %arg) {operandSegmentSizes = array<i64: 1, 1, 1, 1>} : (i32, i32, i32, i32) -> ()
402}
403
404// -----
405
406func.func @failedOperandSizeAttrNegativeValue(%arg: i32) {
407  // expected-error @+1 {{'operandSegmentSizes' attribute cannot have negative elements}}
408  "test.attr_sized_operands"(%arg, %arg, %arg, %arg) {operandSegmentSizes = array<i32: 1, 1, -1, 1>} : (i32, i32, i32, i32) -> ()
409}
410
411// -----
412
413func.func @failedOperandSizeAttrWrongTotalSize(%arg: i32) {
414  // expected-error @+1 {{operand count (4) does not match with the total size (3) specified in attribute 'operandSegmentSizes'}}
415  "test.attr_sized_operands"(%arg, %arg, %arg, %arg) {operandSegmentSizes = array<i32: 0, 1, 1, 1>} : (i32, i32, i32, i32) -> ()
416}
417
418// -----
419
420func.func @failedOperandSizeAttrWrongCount(%arg: i32) {
421  // expected-error @+1 {{test.attr_sized_operands' op operand count (4) does not match with the total size (0) specified in attribute 'operandSegmentSizes}}
422  "test.attr_sized_operands"(%arg, %arg, %arg, %arg) {operandSegmentSizes = array<i32: 2, 1, 1>} : (i32, i32, i32, i32) -> ()
423}
424
425// -----
426
427func.func @succeededOperandSizeAttr(%arg: i32) {
428  // CHECK: test.attr_sized_operands
429  "test.attr_sized_operands"(%arg, %arg, %arg, %arg) {operandSegmentSizes = array<i32: 0, 2, 1, 1>} : (i32, i32, i32, i32) -> ()
430  return
431}
432
433// -----
434
435func.func @failedMissingResultSizeAttr() {
436  // expected-error @+1 {{op result count (4) does not match with the total size (0) specified in attribute 'resultSegmentSizes'}}
437  %0:4 = "test.attr_sized_results"() : () -> (i32, i32, i32, i32)
438}
439
440// -----
441
442func.func @failedResultSizeAttrWrongType() {
443  // expected-error @+1 {{ op result count (4) does not match with the total size (0) specified in attribute 'resultSegmentSizes'}}
444  %0:4 = "test.attr_sized_results"() {resultSegmentSizes = 10} : () -> (i32, i32, i32, i32)
445}
446
447
448// -----
449
450func.func @failedResultSizeAttrWrongElementType() {
451  // expected-error @+1 {{ op result count (4) does not match with the total size (0) specified in attribute 'resultSegmentSizes'}}
452  %0:4 = "test.attr_sized_results"() {resultSegmentSizes = array<i64: 1, 1, 1, 1>} : () -> (i32, i32, i32, i32)
453}
454
455// -----
456
457func.func @failedResultSizeAttrNegativeValue() {
458  // expected-error @+1 {{'resultSegmentSizes' attribute cannot have negative elements}}
459  %0:4 = "test.attr_sized_results"() {resultSegmentSizes = array<i32: 1, 1, -1, 1>} : () -> (i32, i32, i32, i32)
460}
461
462// -----
463
464func.func @failedResultSizeAttrWrongTotalSize() {
465  // expected-error @+1 {{result count (4) does not match with the total size (3) specified in attribute 'resultSegmentSizes'}}
466  %0:4 = "test.attr_sized_results"() {resultSegmentSizes = array<i32: 0, 1, 1, 1>} : () -> (i32, i32, i32, i32)
467}
468
469// -----
470
471func.func @failedResultSizeAttrWrongCount() {
472  // expected-error @+1 {{ op result count (4) does not match with the total size (0) specified in attribute 'resultSegmentSizes'}}
473  %0:4 = "test.attr_sized_results"() {resultSegmentSizes = array<i32: 2, 1, 1>} : () -> (i32, i32, i32, i32)
474}
475
476// -----
477
478func.func @succeededResultSizeAttr() {
479  // CHECK: test.attr_sized_results
480  %0:4 = "test.attr_sized_results"() {resultSegmentSizes = array<i32: 0, 2, 1, 1>} : () -> (i32, i32, i32, i32)
481  return
482}
483
484// -----
485
486// CHECK-LABEL: @succeededOilistTrivial
487func.func @succeededOilistTrivial() {
488  // CHECK: test.oilist_with_keywords_only keyword
489  test.oilist_with_keywords_only keyword
490  // CHECK: test.oilist_with_keywords_only otherKeyword
491  test.oilist_with_keywords_only otherKeyword
492  // CHECK: test.oilist_with_keywords_only keyword otherKeyword
493  test.oilist_with_keywords_only keyword otherKeyword
494  // CHECK: test.oilist_with_keywords_only keyword otherKeyword
495  test.oilist_with_keywords_only otherKeyword keyword
496  // CHECK: test.oilist_with_keywords_only thirdKeyword
497  test.oilist_with_keywords_only thirdKeyword
498  // CHECK: test.oilist_with_keywords_only keyword thirdKeyword
499  test.oilist_with_keywords_only keyword thirdKeyword
500  return
501}
502
503// -----
504
505// CHECK-LABEL: @succeededOilistTrivialProperties
506func.func @succeededOilistTrivialProperties() {
507  // CHECK: test.oilist_with_keywords_only_properties keyword
508  test.oilist_with_keywords_only_properties keyword
509  // CHECK: test.oilist_with_keywords_only_properties otherKeyword
510  test.oilist_with_keywords_only_properties otherKeyword
511  // CHECK: test.oilist_with_keywords_only_properties keyword otherKeyword
512  test.oilist_with_keywords_only_properties keyword otherKeyword
513  // CHECK: test.oilist_with_keywords_only_properties keyword otherKeyword
514  test.oilist_with_keywords_only_properties otherKeyword keyword
515  // CHECK: test.oilist_with_keywords_only_properties thirdKeyword
516  test.oilist_with_keywords_only_properties thirdKeyword
517  // CHECK: test.oilist_with_keywords_only_properties keyword thirdKeyword
518  test.oilist_with_keywords_only_properties keyword thirdKeyword
519  return
520}
521
522// -----
523
524// CHECK-LABEL: @succeededOilistSimple
525func.func @succeededOilistSimple(%arg0 : i32, %arg1 : i32, %arg2 : i32) {
526  // CHECK: test.oilist_with_simple_args keyword %{{.*}} : i32
527  test.oilist_with_simple_args keyword %arg0 : i32
528  // CHECK: test.oilist_with_simple_args otherKeyword %{{.*}} : i32
529  test.oilist_with_simple_args otherKeyword %arg0 : i32
530  // CHECK: test.oilist_with_simple_args thirdKeyword %{{.*}} : i32
531  test.oilist_with_simple_args thirdKeyword %arg0 : i32
532
533  // CHECK: test.oilist_with_simple_args keyword %{{.*}} : i32 otherKeyword %{{.*}} : i32
534  test.oilist_with_simple_args keyword %arg0 : i32 otherKeyword %arg1 : i32
535  // CHECK: test.oilist_with_simple_args keyword %{{.*}} : i32 thirdKeyword %{{.*}} : i32
536  test.oilist_with_simple_args keyword %arg0 : i32 thirdKeyword %arg1 : i32
537  // CHECK: test.oilist_with_simple_args otherKeyword %{{.*}} : i32 thirdKeyword %{{.*}} : i32
538  test.oilist_with_simple_args thirdKeyword %arg0 : i32 otherKeyword %arg1 : i32
539
540  // CHECK: test.oilist_with_simple_args keyword %{{.*}} : i32 otherKeyword %{{.*}} : i32 thirdKeyword %{{.*}} : i32
541  test.oilist_with_simple_args keyword %arg0 : i32 otherKeyword %arg1 : i32 thirdKeyword %arg2 : i32
542  // CHECK: test.oilist_with_simple_args keyword %{{.*}} : i32 otherKeyword %{{.*}} : i32 thirdKeyword %{{.*}} : i32
543  test.oilist_with_simple_args otherKeyword %arg0 : i32 keyword %arg1 : i32 thirdKeyword %arg2 : i32
544  // CHECK: test.oilist_with_simple_args keyword %{{.*}} : i32 otherKeyword %{{.*}} : i32 thirdKeyword %{{.*}} : i32
545  test.oilist_with_simple_args otherKeyword %arg0 : i32 thirdKeyword %arg1 : i32 keyword %arg2 : i32
546  return
547}
548
549// -----
550
551// CHECK-LABEL: @succeededOilistVariadic
552// CHECK-SAME: (%[[ARG0:.*]]: i32, %[[ARG1:.*]]: i32, %[[ARG2:.*]]: i32)
553func.func @succeededOilistVariadic(%arg0: i32, %arg1: i32, %arg2: i32) {
554  // CHECK: test.oilist_variadic_with_parens keyword(%[[ARG0]], %[[ARG1]] : i32, i32)
555  test.oilist_variadic_with_parens keyword (%arg0, %arg1 : i32, i32)
556  // CHECK: test.oilist_variadic_with_parens keyword(%[[ARG0]], %[[ARG1]] : i32, i32) otherKeyword(%[[ARG2]], %[[ARG1]] : i32, i32)
557  test.oilist_variadic_with_parens otherKeyword (%arg2, %arg1 : i32, i32) keyword (%arg0, %arg1 : i32, i32)
558  // CHECK: test.oilist_variadic_with_parens keyword(%[[ARG0]], %[[ARG1]] : i32, i32) otherKeyword(%[[ARG0]], %[[ARG1]] : i32, i32) thirdKeyword(%[[ARG2]], %[[ARG0]], %[[ARG1]] : i32, i32, i32)
559  test.oilist_variadic_with_parens thirdKeyword (%arg2, %arg0, %arg1 : i32, i32, i32) keyword (%arg0, %arg1 : i32, i32) otherKeyword (%arg0, %arg1 : i32, i32)
560  return
561}
562
563// -----
564// CHECK-LABEL: succeededOilistCustom
565// CHECK-SAME: (%[[ARG0:.*]]: i32, %[[ARG1:.*]]: i32, %[[ARG2:.*]]: i32)
566func.func @succeededOilistCustom(%arg0: i32, %arg1: i32, %arg2: i32) {
567  // CHECK: test.oilist_custom private(%[[ARG0]], %[[ARG1]] : i32, i32)
568  test.oilist_custom private (%arg0, %arg1 : i32, i32)
569  // CHECK: test.oilist_custom private(%[[ARG0]], %[[ARG1]] : i32, i32) nowait
570  test.oilist_custom private (%arg0, %arg1 : i32, i32) nowait
571  // CHECK: test.oilist_custom private(%arg0, %arg1 : i32, i32) reduction (%arg1) nowait
572  test.oilist_custom nowait reduction (%arg1) private (%arg0, %arg1 : i32, i32)
573  return
574}
575
576// -----
577
578func.func @failedHasDominanceScopeOutsideDominanceFreeScope() -> () {
579  "test.ssacfg_region"() ({
580    test.graph_region {
581      // expected-error @+1 {{operand #0 does not dominate this use}}
582      %2:3 = "bar"(%1) : (i64) -> (i1,i1,i1)
583    }
584    // expected-note @+1 {{operand defined here}}
585    %1 = "baz"() : () -> (i64)
586  }) : () -> ()
587  return
588}
589
590// -----
591
592// Ensure that SSACFG regions of operations in GRAPH regions are
593// checked for dominance
594func.func @illegalInsideDominanceFreeScope(%cond: i1) -> () {
595  test.graph_region {
596    scf.if %cond {
597      // expected-error @+1 {{operand #0 does not dominate this use}}
598      %2:3 = "bar"(%1) : (i64) -> (i1,i1,i1)
599      // expected-note @+1 {{operand defined here}}
600      %1 = "baz"(%2#0) : (i1) -> (i64)
601    }
602    "terminator"() : () -> ()
603  }
604  return
605}
606
607// -----
608
609// Ensure that SSACFG regions of operations in GRAPH regions are
610// checked for dominance
611func.func @illegalCFGInsideDominanceFreeScope(%cond: i1) -> () {
612  test.graph_region {
613    scf.if %cond {
614      "test.ssacfg_region"() ({
615      ^bb1:
616        // expected-error @+1 {{operand #0 does not dominate this use}}
617        %2:3 = "bar"(%1) : (i64) -> (i1,i1,i1)
618        cf.br ^bb4
619      ^bb2:
620        cf.br ^bb2
621      ^bb4:
622        %1 = "foo"() : ()->i64   // expected-note {{operand defined here}}
623      }) : () -> ()
624    }
625    "terminator"() : () -> ()
626  }
627  return
628}
629
630// -----
631
632// Ensure that GRAPH regions still have all values defined somewhere.
633func.func @illegalCDFGInsideDominanceFreeScope() -> () {
634  test.graph_region {
635    // expected-error @+1 {{use of undeclared SSA value name}}
636    %2:3 = "bar"(%1) : (i64) -> (i1,i1,i1)
637    "terminator"() : () -> ()
638  }
639  return
640}
641
642// -----
643
644func.func @graph_region_cant_have_blocks() {
645  test.graph_region {
646    // expected-error@-1 {{'test.graph_region' op expects graph region #0 to have 0 or 1 blocks}}
647  ^bb42:
648    cf.br ^bb43
649  ^bb43:
650    "terminator"() : () -> ()
651  }
652}
653
654// -----
655
656// Check that we can query traits in types
657func.func @succeeded_type_traits() {
658  // CHECK: "test.result_type_with_trait"() : () -> !test.test_type_with_trait
659  "test.result_type_with_trait"() : () -> !test.test_type_with_trait
660  return
661}
662
663// -----
664
665// Check that we can query traits in types
666func.func @failed_type_traits() {
667  // expected-error@+1 {{result type should have trait 'TestTypeTrait'}}
668  "test.result_type_with_trait"() : () -> i32
669  return
670}
671
672// -----
673
674// Check that we can query traits in attributes
675func.func @succeeded_attr_traits() {
676  // CHECK: "test.attr_with_trait"() <{attr = #test.attr_with_trait}> : () -> ()
677  "test.attr_with_trait"() {attr = #test.attr_with_trait} : () -> ()
678  return
679}
680
681// -----
682
683// Check that we can query traits in attributes
684func.func @failed_attr_traits() {
685  // expected-error@+1 {{'attr' attribute should have trait 'TestAttrTrait'}}
686  "test.attr_with_trait"() {attr = 42 : i32} : () -> ()
687  return
688}
689