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<OpTrait> 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 def DirectiveAttrDictValidA : TestFormat_Op<[{
42 def DirectiveAttrDictValidB : TestFormat_Op<[{
43 attr-dict-with-keyword
46 //===----------------------------------------------------------------------===//
49 // CHECK: error: expected '<' before custom directive name
50 def DirectiveCustomInvalidA : TestFormat_Op<[{
53 // CHECK: error: expected custom directive name identifier
54 def DirectiveCustomInvalidB : TestFormat_Op<[{
57 // CHECK: error: expected '>' after custom directive name
58 def DirectiveCustomInvalidC : TestFormat_Op<[{
61 // CHECK: error: expected '(' before custom directive parameters
62 def DirectiveCustomInvalidD : TestFormat_Op<[{
65 // CHECK: error: only variables and types may be used as parameters to a custom directive
66 def DirectiveCustomInvalidE : TestFormat_Op<[{
67 custom<MyDirective>(operands)
69 // CHECK: error: expected ')' after custom directive parameters
70 def DirectiveCustomInvalidF : TestFormat_Op<[{
71 custom<MyDirective>($operand<
72 }]>, Arguments<(ins I64:$operand)>;
73 // CHECK: error: type directives within a custom directive may only refer to variables
74 def DirectiveCustomInvalidH : TestFormat_Op<[{
75 custom<MyDirective>(type(operands))
79 def DirectiveCustomValidA : TestFormat_Op<[{
80 custom<MyDirective>($operand) attr-dict
81 }]>, Arguments<(ins Optional<I64>:$operand)>;
82 def DirectiveCustomValidB : TestFormat_Op<[{
83 custom<MyDirective>($operand, type($operand), type($result)) attr-dict
84 }]>, Arguments<(ins I64:$operand)>, Results<(outs I64:$result)>;
85 def DirectiveCustomValidC : TestFormat_Op<[{
86 custom<MyDirective>($attr) attr-dict
87 }]>, Arguments<(ins I64Attr:$attr)>;
89 //===----------------------------------------------------------------------===//
92 // CHECK: error: 'functional-type' is only valid as a top-level directive
93 def DirectiveFunctionalTypeInvalidA : TestFormat_Op<[{
94 functional-type(functional-type)
96 // CHECK: error: expected '(' before argument list
97 def DirectiveFunctionalTypeInvalidB : TestFormat_Op<[{
100 // CHECK: error: expected directive, literal, variable, or optional group
101 def DirectiveFunctionalTypeInvalidC : TestFormat_Op<[{
104 // CHECK: error: expected ',' after inputs argument
105 def DirectiveFunctionalTypeInvalidD : TestFormat_Op<[{
106 functional-type(operands
108 // CHECK: error: expected directive, literal, variable, or optional group
109 def DirectiveFunctionalTypeInvalidE : TestFormat_Op<[{
110 functional-type(operands,
112 // CHECK: error: expected ')' after argument list
113 def DirectiveFunctionalTypeInvalidF : TestFormat_Op<[{
114 functional-type(operands, results
117 def DirectiveFunctionalTypeValid : TestFormat_Op<[{
118 functional-type(operands, results) attr-dict
121 //===----------------------------------------------------------------------===//
124 // CHECK: error: 'operands' directive creates overlap in format
125 def DirectiveOperandsInvalidA : TestFormat_Op<[{
128 // CHECK: error: 'operands' directive creates overlap in format
129 def DirectiveOperandsInvalidB : TestFormat_Op<[{
131 }]>, Arguments<(ins I64:$operand)>;
133 def DirectiveOperandsValid : TestFormat_Op<[{
137 //===----------------------------------------------------------------------===//
140 // CHECK: error: 'ref' is only valid within a `custom` directive
141 def DirectiveRefInvalidA : TestFormat_Op<[{
143 }]>, Arguments<(ins I64:$operand)>;
145 // CHECK: error: 'ref' of 'type($operand)' is not bound by a prior 'type' directive
146 def DirectiveRefInvalidB : TestFormat_Op<[{
147 custom<Foo>(ref(type($operand)))
148 }]>, Arguments<(ins I64:$operand)>;
150 // CHECK: error: 'ref' of 'type(operands)' is not bound by a prior 'type' directive
151 def DirectiveRefInvalidC : TestFormat_Op<[{
152 custom<Foo>(ref(type(operands)))
155 // CHECK: error: 'ref' of 'type($result)' is not bound by a prior 'type' directive
156 def DirectiveRefInvalidD : TestFormat_Op<[{
157 custom<Foo>(ref(type($result)))
158 }]>, Results<(outs I64:$result)>;
160 // CHECK: error: 'ref' of 'type(results)' is not bound by a prior 'type' directive
161 def DirectiveRefInvalidE : TestFormat_Op<[{
162 custom<Foo>(ref(type(results)))
165 // CHECK: error: 'ref' of 'successors' is not bound by a prior 'successors' directive
166 def DirectiveRefInvalidF : TestFormat_Op<[{
167 custom<Foo>(ref(successors))
170 // CHECK: error: 'ref' of 'regions' is not bound by a prior 'regions' directive
171 def DirectiveRefInvalidG : TestFormat_Op<[{
172 custom<Foo>(ref(regions))
175 // CHECK: error: expected '(' before argument list
176 def DirectiveRefInvalidH : TestFormat_Op<[{
180 // CHECK: error: expected ')' after argument list
181 def DirectiveRefInvalidI : TestFormat_Op<[{
182 operands custom<Foo>(ref(operands(
185 // CHECK: error: 'ref' of 'operands' is not bound by a prior 'operands' directive
186 def DirectiveRefInvalidJ : TestFormat_Op<[{
187 custom<Foo>(ref(operands))
190 // CHECK: error: 'ref' of 'attr-dict' is not bound by a prior 'attr-dict' directive
191 def DirectiveRefInvalidK : TestFormat_Op<[{
192 custom<Foo>(ref(attr-dict))
195 // CHECK: error: successor 'successor' must be bound before it is referenced
196 def DirectiveRefInvalidL : TestFormat_Op<[{
197 custom<Foo>(ref($successor))
199 let successors = (successor AnySuccessor:$successor);
202 // CHECK: error: region 'region' must be bound before it is referenced
203 def DirectiveRefInvalidM : TestFormat_Op<[{
204 custom<Foo>(ref($region))
206 let regions = (region AnyRegion:$region);
209 // CHECK: error: attribute 'attr' must be bound before it is referenced
210 def DirectiveRefInvalidN : TestFormat_Op<[{
211 custom<Foo>(ref($attr))
212 }]>, Arguments<(ins I64Attr:$attr)>;
215 // CHECK: error: operand 'operand' must be bound before it is referenced
216 def DirectiveRefInvalidO : TestFormat_Op<[{
217 custom<Foo>(ref($operand))
218 }]>, Arguments<(ins I64:$operand)>;
220 //===----------------------------------------------------------------------===//
223 // CHECK: error: 'regions' directive creates overlap in format
224 def DirectiveRegionsInvalidA : TestFormat_Op<[{
225 regions regions attr-dict
227 // CHECK: error: 'regions' directive creates overlap in format
228 def DirectiveRegionsInvalidB : TestFormat_Op<[{
229 $region regions attr-dict
231 let regions = (region AnyRegion:$region);
233 // CHECK: error: 'regions' is only valid as a top-level directive
234 def DirectiveRegionsInvalidC : TestFormat_Op<[{
238 def DirectiveRegionsValid : TestFormat_Op<[{
242 //===----------------------------------------------------------------------===//
245 // CHECK: error: 'results' directive can can only be used as a child to a 'type' directive
246 def DirectiveResultsInvalidA : TestFormat_Op<[{
250 //===----------------------------------------------------------------------===//
253 // CHECK: error: 'successors' is only valid as a top-level directive
254 def DirectiveSuccessorsInvalidA : TestFormat_Op<[{
258 //===----------------------------------------------------------------------===//
261 // CHECK: error: expected '(' before argument list
262 def DirectiveTypeInvalidA : TestFormat_Op<[{
265 // CHECK: error: expected directive, literal, variable, or optional group
266 def DirectiveTypeInvalidB : TestFormat_Op<[{
269 // CHECK: error: expected ')' after argument list
270 def DirectiveTypeInvalidC : TestFormat_Op<[{
274 def DirectiveTypeValid : TestFormat_Op<[{
275 type(operands) attr-dict
278 //===----------------------------------------------------------------------===//
279 // functional-type/type operands
281 // CHECK: error: literals may only be used in a top-level section of the format
282 def DirectiveTypeZOperandInvalidA : TestFormat_Op<[{
285 // CHECK: error: 'operands' 'type' is already bound
286 def DirectiveTypeZOperandInvalidB : TestFormat_Op<[{
287 type(operands) type(operands)
289 // CHECK: error: 'operands' 'type' is already bound
290 def DirectiveTypeZOperandInvalidC : TestFormat_Op<[{
291 type($operand) type(operands)
292 }]>, Arguments<(ins I64:$operand)>;
293 // CHECK: error: 'type' of 'operand' is already bound
294 def DirectiveTypeZOperandInvalidD : TestFormat_Op<[{
295 type(operands) type($operand)
296 }]>, Arguments<(ins I64:$operand)>;
297 // CHECK: error: 'type' of 'operand' is already bound
298 def DirectiveTypeZOperandInvalidE : TestFormat_Op<[{
299 type($operand) type($operand)
300 }]>, Arguments<(ins I64:$operand)>;
301 // CHECK: error: 'results' 'type' is already bound
302 def DirectiveTypeZOperandInvalidF : TestFormat_Op<[{
303 type(results) type(results)
305 // CHECK: error: 'results' 'type' is already bound
306 def DirectiveTypeZOperandInvalidG : TestFormat_Op<[{
307 type($result) type(results)
308 }]>, Results<(outs I64:$result)>;
309 // CHECK: error: 'type' of 'result' is already bound
310 def DirectiveTypeZOperandInvalidH : TestFormat_Op<[{
311 type(results) type($result)
312 }]>, Results<(outs I64:$result)>;
313 // CHECK: error: 'type' of 'result' is already bound
314 def DirectiveTypeZOperandInvalidI : TestFormat_Op<[{
315 type($result) type($result)
316 }]>, Results<(outs I64:$result)>;
318 //===----------------------------------------------------------------------===//
320 //===----------------------------------------------------------------------===//
322 // Test all of the valid literals.
323 // CHECK: error: expected valid literal but got 'a:': keywords should contain only alphanum, '_', '$', or '.' characters
324 def LiteralInvalidA : TestFormat_Op<[{
327 // CHECK: error: expected valid literal but got '1': single character literal must be a letter or one of '_:,=<>()[]{}?+*'
328 def LiteralInvalidB : TestFormat_Op<[{
331 // CHECK: error: expected valid literal but got ':abc': valid keyword starts with a letter or '_'
332 def LiteralInvalidC : TestFormat_Op<[{
336 // CHECK: error: unexpected end of file in literal
337 // CHECK: error: expected directive, literal, variable, or optional group
338 def LiteralInvalidD : TestFormat_Op<[{
342 def LiteralValid : TestFormat_Op<[{
343 `_` `:` `,` `=` `<` `>` `(` `)` `[` `]` `?` `+` `*` ` ` `` `->` `\n` `abc$._`
347 //===----------------------------------------------------------------------===//
349 //===----------------------------------------------------------------------===//
351 // CHECK: error: optional groups can only be used as top-level elements
352 def OptionalInvalidA : TestFormat_Op<[{
353 type(($attr^)?) attr-dict
354 }]>, Arguments<(ins OptionalAttr<I64Attr>:$attr)>;
355 // CHECK: error: expected directive, literal, variable, or optional group
356 def OptionalInvalidB : TestFormat_Op<[{
358 }]>, Arguments<(ins OptionalAttr<I64Attr>:$attr)>;
359 // CHECK: error: optional group specified no anchor element
360 def OptionalInvalidC : TestFormat_Op<[{
362 }]>, Arguments<(ins OptionalAttr<I64Attr>:$attr)>;
363 // CHECK: error: first parsable element of an operand group must be an attribute, literal, operand, or region
364 def OptionalInvalidD : TestFormat_Op<[{
365 (type($operand) $operand^)? attr-dict
366 }]>, Arguments<(ins Optional<I64>:$operand)>;
367 // CHECK: error: only literals, types, and variables can be used within an optional group
368 def OptionalInvalidE : TestFormat_Op<[{
369 (`,` $attr^ type(operands))? attr-dict
370 }]>, Arguments<(ins OptionalAttr<I64Attr>:$attr)>;
371 // CHECK: error: only one element can be marked as the anchor of an optional group
372 def OptionalInvalidF : TestFormat_Op<[{
373 ($attr^ $attr2^) attr-dict
374 }]>, Arguments<(ins OptionalAttr<I64Attr>:$attr, OptionalAttr<I64Attr>:$attr2)>;
375 // CHECK: error: only optional attributes can be used to anchor an optional group
376 def OptionalInvalidG : TestFormat_Op<[{
378 }]>, Arguments<(ins I64Attr:$attr)>;
379 // CHECK: error: only variable length operands can be used within an optional group
380 def OptionalInvalidH : TestFormat_Op<[{
382 }]>, Arguments<(ins I64:$arg)>;
383 // CHECK: error: only literals, types, and variables can be used within an optional group
384 def OptionalInvalidI : TestFormat_Op<[{
385 (functional-type($arg, results)^)? attr-dict
386 }]>, Arguments<(ins Variadic<I64>:$arg)>;
387 // CHECK: error: only literals, types, and variables can be used within an optional group
388 def OptionalInvalidJ : TestFormat_Op<[{
391 // CHECK: error: expected '?' after optional group
392 def OptionalInvalidK : TestFormat_Op<[{
394 }]>, Arguments<(ins Variadic<I64>:$arg)>;
395 // CHECK: error: only variables and types can be used to anchor an optional group
396 def OptionalInvalidL : TestFormat_Op<[{
397 (custom<MyDirective>($arg)^)?
398 }]>, Arguments<(ins I64:$arg)>;
399 // CHECK: error: only variables and types can be used to anchor an optional group
400 def OptionalInvalidM : TestFormat_Op<[{
402 }]>, Arguments<(ins)>;
403 // CHECK: error: expected '(' to start else branch of optional group
404 def OptionalInvalidN : TestFormat_Op<[{
406 }]>, Arguments<(ins Variadic<I64>:$arg)>;
407 // CHECK: error: expected directive, literal, variable, or optional group
408 def OptionalInvalidO : TestFormat_Op<[{
410 }]>, Arguments<(ins Variadic<I64>:$arg)>;
411 // CHECK: error: expected '?' after optional group
412 def OptionalInvalidP : TestFormat_Op<[{
414 }]>, Arguments<(ins Variadic<I64>:$arg)>;
417 def OptionalValidA : TestFormat_Op<[{
421 //===----------------------------------------------------------------------===//
423 //===----------------------------------------------------------------------===//
425 // CHECK: error: expected variable to refer to an argument, region, result, or successor
426 def VariableInvalidA : TestFormat_Op<[{
427 $unknown_arg attr-dict
429 // CHECK: error: attribute 'attr' is already bound
430 def VariableInvalidB : TestFormat_Op<[{
431 $attr $attr attr-dict
432 }]>, Arguments<(ins I64Attr:$attr)>;
433 // CHECK: error: operand 'operand' is already bound
434 def VariableInvalidC : TestFormat_Op<[{
435 $operand $operand attr-dict
436 }]>, Arguments<(ins I64:$operand)>;
437 // CHECK: error: operand 'operand' is already bound
438 def VariableInvalidD : TestFormat_Op<[{
439 operands $operand attr-dict
440 }]>, Arguments<(ins I64:$operand)>;
441 // CHECK: error: result variables can can only be used as a child to a 'type' directive
442 def VariableInvalidE : TestFormat_Op<[{
444 }]>, Results<(outs I64:$result)>;
445 // CHECK: error: successor 'successor' is already bound
446 def VariableInvalidF : TestFormat_Op<[{
447 $successor $successor attr-dict
449 let successors = (successor AnySuccessor:$successor);
451 // CHECK: error: successor 'successor' is already bound
452 def VariableInvalidG : TestFormat_Op<[{
453 successors $successor attr-dict
455 let successors = (successor AnySuccessor:$successor);
457 // CHECK: error: format ambiguity caused by `:` literal found after attribute `attr` which does not have a buildable type
458 def VariableInvalidH : TestFormat_Op<[{
460 }]>, Arguments<(ins ElementsAttr:$attr)>;
461 // CHECK: error: format ambiguity caused by `:` literal found after attribute `attr` which does not have a buildable type
462 def VariableInvalidI : TestFormat_Op<[{
463 (`foo` $attr^)? `:` attr-dict
464 }]>, Arguments<(ins OptionalAttr<ElementsAttr>:$attr)>;
465 // CHECK: error: format ambiguity caused by `:` literal found after attribute `attr` which does not have a buildable type
466 def VariableInvalidJ : TestFormat_Op<[{
467 $attr ` ` `:` attr-dict
468 }]>, Arguments<(ins ElementsAttr:$attr)>;
469 // CHECK: error: region 'region' is already bound
470 def VariableInvalidK : TestFormat_Op<[{
471 $region $region attr-dict
473 let regions = (region AnyRegion:$region);
475 // CHECK: error: region 'region' is already bound
476 def VariableInvalidL : TestFormat_Op<[{
477 regions $region attr-dict
479 let regions = (region AnyRegion:$region);
481 // CHECK: error: regions can only be used at the top level
482 def VariableInvalidM : TestFormat_Op<[{
485 let regions = (region AnyRegion:$region);
487 // CHECK: error: region #0, named 'region', not found
488 def VariableInvalidN : TestFormat_Op<[{
491 let regions = (region AnyRegion:$region);
494 def VariableValidA : TestFormat_Op<[{
496 }]>, Arguments<(ins OptionalAttr<I1Attr>:$attr)>;
497 def VariableValidB : TestFormat_Op<[{
498 (`foo` $attr^)? `:` attr-dict
499 }]>, Arguments<(ins OptionalAttr<I1Attr>:$attr)>;
501 //===----------------------------------------------------------------------===//
503 //===----------------------------------------------------------------------===//
505 // CHECK: error: type of result #0, named 'result', 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($result)' directive to the custom assembly format
507 def ZCoverageInvalidA : TestFormat_Op<[{
509 }]>, Arguments<(ins AnyMemRef:$operand)>, Results<(outs AnyMemRef:$result)>;
510 // CHECK: error: operand #0, named 'operand', not found
511 // CHECK: note: suggest adding a '$operand' directive to the custom assembly format
512 def ZCoverageInvalidB : TestFormat_Op<[{
513 type($result) attr-dict
514 }]>, Arguments<(ins AnyMemRef:$operand)>, Results<(outs AnyMemRef:$result)>;
515 // CHECK: error: type of operand #0, named 'operand', 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($operand)' directive to the custom assembly format
517 def ZCoverageInvalidC : TestFormat_Op<[{
518 $operand type($result) attr-dict
519 }]>, Arguments<(ins AnyMemRef:$operand)>, Results<(outs AnyMemRef:$result)>;
520 // CHECK: error: type of operand #0, named 'operand', is not buildable and a buildable type cannot be inferred
521 // CHECK: note: suggest adding a type constraint to the operation or adding a 'type($operand)' directive to the custom assembly format
522 def ZCoverageInvalidD : TestFormat_Op<[{
524 }]>, Arguments<(ins Variadic<I64>:$operand)>;
525 // CHECK: error: type of result #0, named 'result', is not buildable and a buildable type cannot be inferred
526 // CHECK: note: suggest adding a type constraint to the operation or adding a 'type($result)' directive to the custom assembly format
527 def ZCoverageInvalidE : TestFormat_Op<[{
529 }]>, Results<(outs Variadic<I64>:$result)>;
530 // CHECK: error: successor #0, named 'successor', not found
531 // CHECK: note: suggest adding a '$successor' directive to the custom assembly format
532 def ZCoverageInvalidF : TestFormat_Op<[{
535 let successors = (successor AnySuccessor:$successor);
537 // CHECK: error: type of operand #0, named 'operand', is not buildable and a buildable type cannot be inferred
538 // CHECK: note: suggest adding a type constraint to the operation or adding a 'type($operand)' directive to the custom assembly format
539 def ZCoverageInvalidG : TestFormat_Op<[{
541 }]>, Arguments<(ins Optional<I64>:$operand)>;
542 // CHECK: error: type of result #0, named 'result', is not buildable and a buildable type cannot be inferred
543 // CHECK: note: suggest adding a type constraint to the operation or adding a 'type($result)' directive to the custom assembly format
544 def ZCoverageInvalidH : TestFormat_Op<[{
546 }]>, Results<(outs Optional<I64>:$result)>;
549 def ZCoverageValidA : TestFormat_Op<[{
550 $operand type($operand) type($result) attr-dict
551 }]>, Arguments<(ins AnyMemRef:$operand)>, Results<(outs AnyMemRef:$result)>;
552 def ZCoverageValidB : TestFormat_Op<[{
553 $operand type(operands) type(results) attr-dict
554 }]>, Arguments<(ins AnyMemRef:$operand)>, Results<(outs AnyMemRef:$result)>;
555 def ZCoverageValidC : TestFormat_Op<[{
556 operands functional-type(operands, results) attr-dict
557 }]>, Arguments<(ins AnyMemRef:$operand)>, Results<(outs AnyMemRef:$result)>;
559 // Check that we can infer type equalities from certain traits.
560 def ZCoverageValidD : TestFormat_Op<[{
561 operands type($result) attr-dict
562 }], [SameOperandsAndResultType]>, Arguments<(ins AnyMemRef:$operand)>,
563 Results<(outs AnyMemRef:$result)>;
564 def ZCoverageValidE : TestFormat_Op<[{
565 $operand type($operand) attr-dict
566 }], [SameOperandsAndResultType]>, Arguments<(ins AnyMemRef:$operand)>,
567 Results<(outs AnyMemRef:$result)>;
568 def ZCoverageValidF : TestFormat_Op<[{
569 operands type($other) attr-dict
570 }], [SameTypeOperands]>, Arguments<(ins AnyMemRef:$operand, AnyMemRef:$other)>;
571 def ZCoverageValidG : TestFormat_Op<[{
572 operands type($other) attr-dict
573 }], [AllTypesMatch<["operand", "other"]>]>,
574 Arguments<(ins AnyMemRef:$operand, AnyMemRef:$other)>;
575 def ZCoverageValidH : TestFormat_Op<[{
576 operands type($result) attr-dict
577 }], [AllTypesMatch<["operand", "result"]>]>,
578 Arguments<(ins AnyMemRef:$operand)>, Results<(outs AnyMemRef:$result)>;
579 def ZCoverageValidI : TestFormat_Op<[{
580 operands type(operands) attr-dict
581 }], [InferTypeOpInterface]>, Arguments<(ins Variadic<I64>:$inputs)>, Results<(outs I64:$result)>;