1 // RUN: mlir-tblgen -gen-op-decls -asmformat-error-is-fatal=false -I %S/../../include %s -o=%t 2>&1 | FileCheck %s
3 // This file contains tests for the specification of the declarative op format.
5 include "mlir/IR/OpBase.td"
6 include "mlir/Interfaces/InferTypeOpInterface.td"
8 def TestDialect : Dialect {
11 class TestFormat_Op<string fmt, list<Trait> traits = []>
12 : Op<TestDialect, "format_op", traits> {
13 let assemblyFormat = fmt;
16 //===----------------------------------------------------------------------===//
18 //===----------------------------------------------------------------------===//
20 //===----------------------------------------------------------------------===//
23 // CHECK: error: 'attr-dict' directive not found
24 def DirectiveAttrDictInvalidA : TestFormat_Op<[{
26 // CHECK: error: 'attr-dict' directive has already been seen
27 def DirectiveAttrDictInvalidB : TestFormat_Op<[{
30 // CHECK: error: 'attr-dict' directive has already been seen
31 def DirectiveAttrDictInvalidC : TestFormat_Op<[{
32 attr-dict attr-dict-with-keyword
34 // CHECK: error: 'attr-dict' directive can only be used as a top-level directive
35 def DirectiveAttrDictInvalidD : TestFormat_Op<[{
39 //===----------------------------------------------------------------------===//
42 // CHECK: error: expected '<' before custom directive name
43 def DirectiveCustomInvalidA : TestFormat_Op<[{
46 // CHECK: error: expected custom directive name identifier
47 def DirectiveCustomInvalidB : TestFormat_Op<[{
50 // CHECK: error: expected '>' after custom directive name
51 def DirectiveCustomInvalidC : TestFormat_Op<[{
54 // CHECK: error: expected '(' before custom directive parameters
55 def DirectiveCustomInvalidD : TestFormat_Op<[{
58 // CHECK: error: only variables and types may be used as parameters to a custom directive
59 def DirectiveCustomInvalidE : TestFormat_Op<[{
60 custom<MyDirective>(operands)
62 // CHECK: error: expected ')' after custom directive parameters
63 def DirectiveCustomInvalidF : TestFormat_Op<[{
64 custom<MyDirective>($operand<
65 }]>, Arguments<(ins I64:$operand)>;
66 // CHECK: error: type directives within a custom directive may only refer to variables
67 def DirectiveCustomInvalidH : TestFormat_Op<[{
68 custom<MyDirective>(type(operands))
71 //===----------------------------------------------------------------------===//
74 // CHECK: error: 'functional-type' is only valid as a top-level directive
75 def DirectiveFunctionalTypeInvalidA : TestFormat_Op<[{
76 functional-type(functional-type)
78 // CHECK: error: expected '(' before argument list
79 def DirectiveFunctionalTypeInvalidB : TestFormat_Op<[{
82 // CHECK: error: expected literal, variable, directive, or optional group
83 def DirectiveFunctionalTypeInvalidC : TestFormat_Op<[{
86 // CHECK: error: expected ',' after inputs argument
87 def DirectiveFunctionalTypeInvalidD : TestFormat_Op<[{
88 functional-type(operands
90 // CHECK: error: expected literal, variable, directive, or optional group
91 def DirectiveFunctionalTypeInvalidE : TestFormat_Op<[{
92 functional-type(operands,
94 // CHECK: error: expected ')' after argument list
95 def DirectiveFunctionalTypeInvalidF : TestFormat_Op<[{
96 functional-type(operands, results
99 //===----------------------------------------------------------------------===//
102 // CHECK: error: 'operands' directive creates overlap in format
103 def DirectiveOperandsInvalidA : TestFormat_Op<[{
106 // CHECK: error: 'operands' directive creates overlap in format
107 def DirectiveOperandsInvalidB : TestFormat_Op<[{
109 }]>, Arguments<(ins I64:$operand)>;
111 //===----------------------------------------------------------------------===//
114 // CHECK: error: 'ref' is only valid within a `custom` directive
115 def DirectiveRefInvalidA : TestFormat_Op<[{
117 }]>, Arguments<(ins I64:$operand)>;
119 // CHECK: error: 'ref' of 'type($operand)' is not bound by a prior 'type' directive
120 def DirectiveRefInvalidB : TestFormat_Op<[{
121 custom<Foo>(ref(type($operand)))
122 }]>, Arguments<(ins I64:$operand)>;
124 // CHECK: error: 'ref' of 'type(operands)' is not bound by a prior 'type' directive
125 def DirectiveRefInvalidC : TestFormat_Op<[{
126 custom<Foo>(ref(type(operands)))
129 // CHECK: error: 'ref' of 'type($result)' is not bound by a prior 'type' directive
130 def DirectiveRefInvalidD : TestFormat_Op<[{
131 custom<Foo>(ref(type($result)))
132 }]>, Results<(outs I64:$result)>;
134 // CHECK: error: 'ref' of 'type(results)' is not bound by a prior 'type' directive
135 def DirectiveRefInvalidE : TestFormat_Op<[{
136 custom<Foo>(ref(type(results)))
139 // CHECK: error: 'ref' of 'successors' is not bound by a prior 'successors' directive
140 def DirectiveRefInvalidF : TestFormat_Op<[{
141 custom<Foo>(ref(successors))
144 // CHECK: error: 'ref' of 'regions' is not bound by a prior 'regions' directive
145 def DirectiveRefInvalidG : TestFormat_Op<[{
146 custom<Foo>(ref(regions))
149 // CHECK: error: expected '(' before argument list
150 def DirectiveRefInvalidH : TestFormat_Op<[{
154 // CHECK: error: expected ')' after argument list
155 def DirectiveRefInvalidI : TestFormat_Op<[{
156 operands custom<Foo>(ref(operands(
159 // CHECK: error: 'ref' of 'operands' is not bound by a prior 'operands' directive
160 def DirectiveRefInvalidJ : TestFormat_Op<[{
161 custom<Foo>(ref(operands))
164 // CHECK: error: 'ref' of 'attr-dict' is not bound by a prior 'attr-dict' directive
165 def DirectiveRefInvalidK : TestFormat_Op<[{
166 custom<Foo>(ref(attr-dict))
169 // CHECK: error: successor 'successor' must be bound before it is referenced
170 def DirectiveRefInvalidL : TestFormat_Op<[{
171 custom<Foo>(ref($successor))
173 let successors = (successor AnySuccessor:$successor);
176 // CHECK: error: region 'region' must be bound before it is referenced
177 def DirectiveRefInvalidM : TestFormat_Op<[{
178 custom<Foo>(ref($region))
180 let regions = (region AnyRegion:$region);
183 // CHECK: error: attribute 'attr' must be bound before it is referenced
184 def DirectiveRefInvalidN : TestFormat_Op<[{
185 custom<Foo>(ref($attr))
186 }]>, Arguments<(ins I64Attr:$attr)>;
189 // CHECK: error: operand 'operand' must be bound before it is referenced
190 def DirectiveRefInvalidO : TestFormat_Op<[{
191 custom<Foo>(ref($operand))
192 }]>, Arguments<(ins I64:$operand)>;
194 //===----------------------------------------------------------------------===//
197 // CHECK: error: 'regions' directive creates overlap in format
198 def DirectiveRegionsInvalidA : TestFormat_Op<[{
199 regions regions attr-dict
201 // CHECK: error: 'regions' directive creates overlap in format
202 def DirectiveRegionsInvalidB : TestFormat_Op<[{
203 $region regions attr-dict
205 let regions = (region AnyRegion:$region);
207 // CHECK: error: 'regions' is only valid as a top-level directive
208 def DirectiveRegionsInvalidC : TestFormat_Op<[{
211 // CHECK: error: format ambiguity caused by `attr-dict` directive followed by region `foo`
212 // CHECK: note: try using `attr-dict-with-keyword` instead
213 def DirectiveRegionsInvalidD : TestFormat_Op<[{
216 let regions = (region AnyRegion:$foo);
219 //===----------------------------------------------------------------------===//
222 // CHECK: error: 'results' directive can can only be used as a child to a 'type' directive
223 def DirectiveResultsInvalidA : TestFormat_Op<[{
227 //===----------------------------------------------------------------------===//
230 // CHECK: error: 'successors' is only valid as a top-level directive
231 def DirectiveSuccessorsInvalidA : TestFormat_Op<[{
235 //===----------------------------------------------------------------------===//
238 // CHECK: error: expected '(' before argument list
239 def DirectiveTypeInvalidA : TestFormat_Op<[{
242 // CHECK: error: expected literal, variable, directive, or optional group
243 def DirectiveTypeInvalidB : TestFormat_Op<[{
246 // CHECK: error: expected ')' after argument list
247 def DirectiveTypeInvalidC : TestFormat_Op<[{
251 //===----------------------------------------------------------------------===//
252 // functional-type/type operands
254 // CHECK: error: literals may only be used in the top-level section of the format
255 def DirectiveTypeZOperandInvalidA : TestFormat_Op<[{
258 // CHECK: error: 'operands' 'type' is already bound
259 def DirectiveTypeZOperandInvalidB : TestFormat_Op<[{
260 type(operands) type(operands)
262 // CHECK: error: 'operands' 'type' is already bound
263 def DirectiveTypeZOperandInvalidC : TestFormat_Op<[{
264 type($operand) type(operands)
265 }]>, Arguments<(ins I64:$operand)>;
266 // CHECK: error: 'type' of 'operand' is already bound
267 def DirectiveTypeZOperandInvalidD : TestFormat_Op<[{
268 type(operands) type($operand)
269 }]>, Arguments<(ins I64:$operand)>;
270 // CHECK: error: 'type' of 'operand' is already bound
271 def DirectiveTypeZOperandInvalidE : TestFormat_Op<[{
272 type($operand) type($operand)
273 }]>, Arguments<(ins I64:$operand)>;
274 // CHECK: error: 'results' 'type' is already bound
275 def DirectiveTypeZOperandInvalidF : TestFormat_Op<[{
276 type(results) type(results)
278 // CHECK: error: 'results' 'type' is already bound
279 def DirectiveTypeZOperandInvalidG : TestFormat_Op<[{
280 type($result) type(results)
281 }]>, Results<(outs I64:$result)>;
282 // CHECK: error: 'type' of 'result' is already bound
283 def DirectiveTypeZOperandInvalidH : TestFormat_Op<[{
284 type(results) type($result)
285 }]>, Results<(outs I64:$result)>;
286 // CHECK: error: 'type' of 'result' is already bound
287 def DirectiveTypeZOperandInvalidI : TestFormat_Op<[{
288 type($result) type($result)
289 }]>, Results<(outs I64:$result)>;
291 //===----------------------------------------------------------------------===//
293 //===----------------------------------------------------------------------===//
295 // Test all of the valid literals.
296 // CHECK: error: expected valid literal but got 'a:': keywords should contain only alphanum, '_', '$', or '.' characters
297 def LiteralInvalidA : TestFormat_Op<[{
300 // CHECK: error: expected valid literal but got '1': single character literal must be a letter or one of '_:,=<>()[]{}?+*'
301 def LiteralInvalidB : TestFormat_Op<[{
304 // CHECK: error: expected valid literal but got ':abc': valid keyword starts with a letter or '_'
305 def LiteralInvalidC : TestFormat_Op<[{
309 // CHECK: error: unexpected end of file in literal
310 // CHECK: error: expected literal, variable, directive, or optional group
311 def LiteralInvalidD : TestFormat_Op<[{
315 //===----------------------------------------------------------------------===//
317 //===----------------------------------------------------------------------===//
319 // CHECK: error: format ambiguity because bar is used in two adjacent oilist elements.
320 def OIListAdjacentOIList : TestFormat_Op<[{
321 oilist ( `foo` | `bar` ) oilist ( `bar` | `buzz` ) attr-dict
323 // CHECK: error: expected literal, but got ')'
324 def OIListErrorExpectedLiteral : TestFormat_Op<[{
325 oilist( `keyword` | ) attr-dict
327 // CHECK: error: expected literal, but got ')'
328 def OIListErrorExpectedEmpty : TestFormat_Op<[{
331 // CHECK: error: expected literal, but got '$arg0'
332 def OIListErrorNoLiteral : TestFormat_Op<[{
333 oilist( $arg0 `:` type($arg0) | $arg1 `:` type($arg1) ) attr-dict
334 }], [AttrSizedOperandSegments]>, Arguments<(ins Optional<AnyType>:$arg0, Optional<AnyType>:$arg1)>;
335 // CHECK: error: format ambiguity because foo is used both in oilist element and the adjacent literal.
336 def OIListLiteralAmbiguity : TestFormat_Op<[{
337 oilist( `foo` | `bar` ) `foo` attr-dict
339 // CHECK: error: expected '(' before oilist argument list
340 def OIListStartingToken : TestFormat_Op<[{
341 oilist `wrong` attr-dict
344 //===----------------------------------------------------------------------===//
346 //===----------------------------------------------------------------------===//
348 // CHECK: error: optional groups can only be used as top-level elements
349 def OptionalInvalidA : TestFormat_Op<[{
350 type(($attr^)?) attr-dict
351 }]>, Arguments<(ins OptionalAttr<I64Attr>:$attr)>;
352 // CHECK: error: expected literal, variable, directive, or optional group
353 def OptionalInvalidB : TestFormat_Op<[{
355 }]>, Arguments<(ins OptionalAttr<I64Attr>:$attr)>;
356 // CHECK: error: optional group has no anchor element
357 def OptionalInvalidC : TestFormat_Op<[{
359 }]>, Arguments<(ins OptionalAttr<I64Attr>:$attr)>;
360 // CHECK: error: first parsable element of an optional group must be a literal, variable, or custom directive
361 def OptionalInvalidD : TestFormat_Op<[{
362 (type($operand) $operand^)? attr-dict
363 }]>, Arguments<(ins Optional<I64>:$operand)>;
364 // CHECK: error: only literals, types, and variables can be used within an optional group
365 def OptionalInvalidE : TestFormat_Op<[{
366 (`,` $attr^ type(operands))? attr-dict
367 }]>, Arguments<(ins OptionalAttr<I64Attr>:$attr)>;
368 // CHECK: error: only one element can be marked as the anchor of an optional group
369 def OptionalInvalidF : TestFormat_Op<[{
370 ($attr^ $attr2^)? attr-dict
371 }]>, Arguments<(ins OptionalAttr<I64Attr>:$attr, OptionalAttr<I64Attr>:$attr2)>;
372 // CHECK: error: only optional or default-valued attributes can be used to anchor an optional group
373 def OptionalInvalidG : TestFormat_Op<[{
375 }]>, Arguments<(ins I64Attr:$attr)>;
376 // CHECK: error: only variable length operands can be used within an optional group
377 def OptionalInvalidH : TestFormat_Op<[{
379 }]>, Arguments<(ins I64:$arg)>;
380 // CHECK: error: only literals, types, and variables can be used within an optional group
381 def OptionalInvalidI : TestFormat_Op<[{
382 (functional-type($arg, results)^)? attr-dict
383 }]>, Arguments<(ins Variadic<I64>:$arg)>;
384 // CHECK: error: only literals, types, and variables can be used within an optional group
385 def OptionalInvalidJ : TestFormat_Op<[{
388 // CHECK: error: expected '?' after optional group
389 def OptionalInvalidK : TestFormat_Op<[{
391 }]>, Arguments<(ins Variadic<I64>:$arg)>;
392 // CHECK: error: only variable length operands can be used within an optional group
393 def OptionalInvalidL : TestFormat_Op<[{
394 (custom<MyDirective>($arg)^)?
395 }]>, Arguments<(ins I64:$arg)>;
396 // CHECK: error: only variables and types can be used to anchor an optional group
397 def OptionalInvalidM : TestFormat_Op<[{
399 }]>, Arguments<(ins)>;
400 // CHECK: error: expected '(' to start else branch of optional group
401 def OptionalInvalidN : TestFormat_Op<[{
403 }]>, Arguments<(ins Variadic<I64>:$arg)>;
404 // CHECK: error: expected literal, variable, directive, or optional group
405 def OptionalInvalidO : TestFormat_Op<[{
407 }]>, Arguments<(ins Variadic<I64>:$arg)>;
408 // CHECK: error: expected '?' after optional group
409 def OptionalInvalidP : TestFormat_Op<[{
411 }]>, Arguments<(ins Variadic<I64>:$arg)>;
413 //===----------------------------------------------------------------------===//
415 //===----------------------------------------------------------------------===//
417 // CHECK: error: strings may only be used as 'custom' directive arguments
418 def StringInvalidA : TestFormat_Op<[{ "foo" }]>;
420 //===----------------------------------------------------------------------===//
422 //===----------------------------------------------------------------------===//
424 // CHECK: error: expected variable to refer to an argument, region, result, or successor
425 def VariableInvalidA : TestFormat_Op<[{
426 $unknown_arg attr-dict
428 // CHECK: error: attribute 'attr' is already bound
429 def VariableInvalidB : TestFormat_Op<[{
430 $attr $attr attr-dict
431 }]>, Arguments<(ins I64Attr:$attr)>;
432 // CHECK: error: operand 'operand' is already bound
433 def VariableInvalidC : TestFormat_Op<[{
434 $operand $operand attr-dict
435 }]>, Arguments<(ins I64:$operand)>;
436 // CHECK: error: operand 'operand' is already bound
437 def VariableInvalidD : TestFormat_Op<[{
438 operands $operand attr-dict
439 }]>, Arguments<(ins I64:$operand)>;
440 // CHECK: error: result variables can can only be used as a child to a 'type' directive
441 def VariableInvalidE : TestFormat_Op<[{
443 }]>, Results<(outs I64:$result)>;
444 // CHECK: error: successor 'successor' is already bound
445 def VariableInvalidF : TestFormat_Op<[{
446 $successor $successor attr-dict
448 let successors = (successor AnySuccessor:$successor);
450 // CHECK: error: successor 'successor' is already bound
451 def VariableInvalidG : TestFormat_Op<[{
452 successors $successor attr-dict
454 let successors = (successor AnySuccessor:$successor);
456 // CHECK: error: region 'region' is already bound
457 def VariableInvalidK : TestFormat_Op<[{
458 $region $region attr-dict
460 let regions = (region AnyRegion:$region);
462 // CHECK: error: region 'region' is already bound
463 def VariableInvalidL : TestFormat_Op<[{
464 regions $region attr-dict
466 let regions = (region AnyRegion:$region);
468 // CHECK: error: regions can only be used at the top level
469 def VariableInvalidM : TestFormat_Op<[{
472 let regions = (region AnyRegion:$region);
474 // CHECK: error: region #0, named 'region', not found
475 def VariableInvalidN : TestFormat_Op<[{
478 let regions = (region AnyRegion:$region);
481 // CHECK: error: property 'prop' is already bound
482 def VariableInvalidO : TestFormat_Op<[{
483 custom<Test>($prop, $prop) attr-dict
484 }]>, Arguments<(ins IntProperty<"int64_t">:$prop)>;
486 // CHECK: error: property 'prop' must be bound before it is referenced
487 def VariableInvalidP : TestFormat_Op<[{
488 custom<Test>(ref($prop)) attr-dict
489 }]>, Arguments<(ins IntProperty<"int64_t">:$prop)>;
491 //===----------------------------------------------------------------------===//
493 //===----------------------------------------------------------------------===//
495 // CHECK: error: type of result #0, named 'result', is not buildable and a buildable type cannot be inferred
496 // CHECK: note: suggest adding a type constraint to the operation or adding a 'type($result)' directive to the custom assembly format
497 def ZCoverageInvalidA : TestFormat_Op<[{
499 }]>, Arguments<(ins AnyMemRef:$operand)>, Results<(outs AnyMemRef:$result)>;
500 // CHECK: error: operand #0, named 'operand', not found
501 // CHECK: note: suggest adding a '$operand' directive to the custom assembly format
502 def ZCoverageInvalidB : TestFormat_Op<[{
503 type($result) attr-dict
504 }]>, Arguments<(ins AnyMemRef:$operand)>, Results<(outs AnyMemRef:$result)>;
505 // CHECK: error: type of operand #0, named 'operand', is not buildable and a buildable type cannot be inferred
506 // CHECK: note: suggest adding a type constraint to the operation or adding a 'type($operand)' directive to the custom assembly format
507 def ZCoverageInvalidC : TestFormat_Op<[{
508 $operand type($result) attr-dict
509 }]>, Arguments<(ins AnyMemRef:$operand)>, Results<(outs AnyMemRef:$result)>;
510 // CHECK: error: type of operand #0, named 'operand', is not buildable and a buildable type cannot be inferred
511 // CHECK: note: suggest adding a type constraint to the operation or adding a 'type($operand)' directive to the custom assembly format
512 def ZCoverageInvalidD : TestFormat_Op<[{
514 }]>, Arguments<(ins Variadic<I64>:$operand)>;
515 // CHECK: error: type of result #0, named 'result', is not buildable and a buildable type cannot be inferred
516 // CHECK: note: suggest adding a type constraint to the operation or adding a 'type($result)' directive to the custom assembly format
517 def ZCoverageInvalidE : TestFormat_Op<[{
519 }]>, Results<(outs Variadic<I64>:$result)>;
520 // CHECK: error: successor #0, named 'successor', not found
521 // CHECK: note: suggest adding a '$successor' directive to the custom assembly format
522 def ZCoverageInvalidF : TestFormat_Op<[{
525 let successors = (successor AnySuccessor:$successor);
527 // CHECK: error: type of operand #0, named 'operand', is not buildable and a buildable type cannot be inferred
528 // CHECK: note: suggest adding a type constraint to the operation or adding a 'type($operand)' directive to the custom assembly format
529 def ZCoverageInvalidG : TestFormat_Op<[{
531 }]>, Arguments<(ins Optional<I64>:$operand)>;
532 // CHECK: error: type of result #0, named 'result', is not buildable and a buildable type cannot be inferred
533 // CHECK: note: suggest adding a type constraint to the operation or adding a 'type($result)' directive to the custom assembly format
534 def ZCoverageInvalidH : TestFormat_Op<[{
536 }]>, Results<(outs Optional<I64>:$result)>;