Fix GCC build problem with 288f05f related to SmallVector. (#116958)
[llvm-project.git] / mlir / test / lib / Dialect / Test / TestOpsSyntax.td
blob795b9da955632c1381e38df6af9e96e9b1905f68
2 //===-- TestOpsSyntax.td - Operations for testing syntax ---*- tablegen -*-===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
10 #ifndef TEST_OPS_SYNTAX
11 #define TEST_OPS_SYNTAX
13 include "TestAttrDefs.td"
14 include "TestDialect.td"
15 include "TestTypeDefs.td"
16 include "mlir/Interfaces/InferTypeOpInterface.td"
17 include "mlir/IR/OpBase.td"
19 class TEST_Op<string mnemonic, list<Trait> traits = []> :
20     Op<Test_Dialect, mnemonic, traits>;
22 def WrappingRegionOp : TEST_Op<"wrapping_region",
23     [SingleBlockImplicitTerminator<"TestReturnOp">]> {
24   let summary =  "wrapping region operation";
25   let description = [{
26     Test op wrapping another op in a region, to test calling
27     parseGenericOperation from the custom parser.
28   }];
30   let results = (outs Variadic<AnyType>);
31   let regions = (region SizedRegion<1>:$region);
32   let hasCustomAssemblyFormat = 1;
35 def PrettyPrintedRegionOp : TEST_Op<"pretty_printed_region",
36     [SingleBlockImplicitTerminator<"TestReturnOp">]> {
37   let summary =  "pretty_printed_region operation";
38   let description = [{
39     Test-op can be printed either in a "pretty" or "non-pretty" way based on
40     some criteria. The custom parser parsers both the versions while testing
41     APIs: parseCustomOperationName & parseGenericOperationAfterOpName.
42   }];
43   let arguments = (ins
44     AnyType:$input1,
45     AnyType:$input2
46   );
48   let results = (outs AnyType);
49   let regions = (region SizedRegion<1>:$region);
50   let hasCustomAssemblyFormat = 1;
53 def PolyForOp : TEST_Op<"polyfor", [OpAsmOpInterface]> {
54   let summary =  "polyfor operation";
55   let description = [{
56     Test op with multiple region arguments, each argument of index type.
57   }];
58   let extraClassDeclaration = [{
59     void getAsmBlockArgumentNames(mlir::Region &region,
60                                   mlir::OpAsmSetValueNameFn setNameFn);
61   }];
62   let regions = (region SizedRegion<1>:$region);
63   let hasCustomAssemblyFormat = 1;
66 def TestAttrWithLoc : TEST_Op<"attr_with_loc"> {
67   let summary = "op's attribute has a location";
68   let arguments = (ins AnyAttr:$loc, AnyAttr:$value);
69   let assemblyFormat = "`(` $value `` custom<OptionalLoc>($loc) `)` attr-dict";
72 // -----
74 // This is used to test that the fallback for a custom op's parser and printer
75 // is the dialect parser and printer hooks.
76 def CustomFormatFallbackOp : TEST_Op<"dialect_custom_format_fallback">;
78 // Ops related to OIList primitive
79 def OIListTrivial : TEST_Op<"oilist_with_keywords_only"> {
80   let arguments = (ins UnitAttr:$keyword, UnitAttr:$otherKeyword,
81                        UnitAttr:$diffNameUnitAttrKeyword);
82   let assemblyFormat = [{
83     oilist( `keyword` $keyword
84           | `otherKeyword` $otherKeyword
85           | `thirdKeyword` $diffNameUnitAttrKeyword) attr-dict
86   }];
89 // Ops related to OIList primitive
90 def OIListTrivialProperties : TEST_Op<"oilist_with_keywords_only_properties"> {
91   let arguments = (ins UnitProperty:$keyword, UnitProperty:$otherKeyword,
92                        UnitProperty:$diffNameUnitPropertyKeyword);
93   let assemblyFormat = [{
94     oilist( `keyword` $keyword
95           | `otherKeyword` $otherKeyword
96           | `thirdKeyword` $diffNameUnitPropertyKeyword) attr-dict
97   }];
100 def OIListSimple : TEST_Op<"oilist_with_simple_args", [AttrSizedOperandSegments]> {
101   let arguments = (ins Optional<AnyType>:$arg0,
102                        Optional<AnyType>:$arg1,
103                        Optional<AnyType>:$arg2);
104   let assemblyFormat = [{
105     oilist( `keyword` $arg0 `:` type($arg0)
106           | `otherKeyword` $arg1 `:` type($arg1)
107           | `thirdKeyword` $arg2 `:` type($arg2) ) attr-dict
108   }];
111 def OIListVariadic : TEST_Op<"oilist_variadic_with_parens", [AttrSizedOperandSegments]> {
112   let arguments = (ins Variadic<AnyType>:$arg0,
113                        Variadic<AnyType>:$arg1,
114                        Variadic<AnyType>:$arg2);
115   let assemblyFormat = [{
116     oilist( `keyword` `(` $arg0 `:` type($arg0) `)`
117           | `otherKeyword` `(` $arg1 `:` type($arg1) `)`
118           | `thirdKeyword` `(` $arg2 `:` type($arg2) `)`) attr-dict
119   }];
122 def OIListCustom : TEST_Op<"oilist_custom", [AttrSizedOperandSegments]> {
123   let arguments = (ins Variadic<AnyType>:$arg0,
124                        Optional<I32>:$optOperand,
125                        UnitAttr:$nowait);
126   let assemblyFormat = [{
127     oilist( `private` `(` $arg0 `:` type($arg0) `)`
128           | `reduction` custom<CustomOptionalOperand>($optOperand)
129           | `nowait` $nowait
130     ) attr-dict
131   }];
134 def OIListAllowedLiteral : TEST_Op<"oilist_allowed_literal"> {
135   let assemblyFormat = [{
136     oilist( `foo` | `bar` ) `buzz` attr-dict
137   }];
140 def TestEllipsisOp : TEST_Op<"ellipsis"> {
141   let arguments = (ins Variadic<AnyType>:$operands, UnitAttr:$variadic);
142   let assemblyFormat = [{
143     `(` $operands (`...` $variadic^)? `)` attr-dict `:` type($operands) `...`
144   }];
147 def ElseAnchorOp : TEST_Op<"else_anchor"> {
148   let arguments = (ins Optional<AnyType>:$a);
149   let assemblyFormat = "`(` (`?`) : (`` $a^ `:` type($a))? `)` attr-dict";
152 // This is used to test that the default dialect is not elided when printing an
153 // op with dots in the name to avoid parsing ambiguity.
154 def OpWithDotInNameOp : TEST_Op<"op.with_dot_in_name"> {
155   let assemblyFormat = "attr-dict";
158 // --------------
160 //===----------------------------------------------------------------------===//
161 // Test Op Asm Format
162 //===----------------------------------------------------------------------===//
164 def FormatLiteralOp : TEST_Op<"format_literal_op"> {
165   let assemblyFormat = [{
166     `keyword_$.` `->` `:` `,` `=` `<` `>` `(` `)` `[` `]` `` `(` ` ` `)`
167     `?` `+` `*` `{` `\n` `}` attr-dict
168   }];
171 // Test that we elide attributes that are within the syntax.
172 def FormatAttrOp : TEST_Op<"format_attr_op"> {
173   let arguments = (ins I64Attr:$attr);
174   let assemblyFormat = "$attr attr-dict";
177 // Test that we elide optional attributes that are within the syntax.
178 def FormatOptAttrAOp : TEST_Op<"format_opt_attr_op_a"> {
179   let arguments = (ins OptionalAttr<I64Attr>:$opt_attr);
180   let assemblyFormat = "(`(` $opt_attr^ `)` )? attr-dict";
182 def FormatOptAttrBOp : TEST_Op<"format_opt_attr_op_b"> {
183   let arguments = (ins OptionalAttr<I64Attr>:$opt_attr);
184   let assemblyFormat = "($opt_attr^)? attr-dict";
187 // Test that we format symbol name attributes properly.
188 def FormatSymbolNameAttrOp : TEST_Op<"format_symbol_name_attr_op"> {
189   let arguments = (ins SymbolNameAttr:$attr);
190   let assemblyFormat = "$attr attr-dict";
193 // Test that we format optional symbol name attributes properly.
194 def FormatOptSymbolNameAttrOp : TEST_Op<"format_opt_symbol_name_attr_op"> {
195   let arguments = (ins OptionalAttr<SymbolNameAttr>:$opt_attr);
196   let assemblyFormat = "($opt_attr^)? attr-dict";
199 // Test that we format optional symbol reference attributes properly.
200 def FormatOptSymbolRefAttrOp : TEST_Op<"format_opt_symbol_ref_attr_op"> {
201   let arguments = (ins OptionalAttr<SymbolRefAttr>:$opt_attr);
202   let assemblyFormat = "($opt_attr^)? attr-dict";
205 // Test that we elide attributes that are within the syntax.
206 def FormatAttrDictWithKeywordOp : TEST_Op<"format_attr_dict_w_keyword"> {
207   let arguments = (ins I64Attr:$attr, OptionalAttr<I64Attr>:$opt_attr);
208   let assemblyFormat = "attr-dict-with-keyword";
211 // Test that we don't need to provide types in the format if they are buildable.
212 def FormatBuildableTypeOp : TEST_Op<"format_buildable_type_op"> {
213   let arguments = (ins I64:$buildable);
214   let results = (outs I64:$buildable_res);
215   let assemblyFormat = "$buildable attr-dict";
218 // Test various mixings of region formatting.
219 class FormatRegionBase<string suffix, string fmt>
220     : TEST_Op<"format_region_" # suffix # "_op"> {
221   let regions = (region AnyRegion:$region);
222   let assemblyFormat = fmt;
224 def FormatRegionAOp : FormatRegionBase<"a", [{
225   regions attr-dict
226 }]>;
227 def FormatRegionBOp : FormatRegionBase<"b", [{
228   $region attr-dict
229 }]>;
230 def FormatRegionCOp : FormatRegionBase<"c", [{
231   (`region` $region^)? attr-dict
232 }]>;
233 class FormatVariadicRegionBase<string suffix, string fmt>
234     : TEST_Op<"format_variadic_region_" # suffix # "_op"> {
235   let regions = (region VariadicRegion<AnyRegion>:$regions);
236   let assemblyFormat = fmt;
238 def FormatVariadicRegionAOp : FormatVariadicRegionBase<"a", [{
239   $regions attr-dict
240 }]>;
241 def FormatVariadicRegionBOp : FormatVariadicRegionBase<"b", [{
242   ($regions^ `found_regions`)? attr-dict
243 }]>;
244 class FormatRegionImplicitTerminatorBase<string suffix, string fmt>
245     : TEST_Op<"format_implicit_terminator_region_" # suffix # "_op",
246               [SingleBlockImplicitTerminator<"TestReturnOp">]> {
247   let regions = (region AnyRegion:$region);
248   let assemblyFormat = fmt;
250 def FormatFormatRegionImplicitTerminatorAOp
251     : FormatRegionImplicitTerminatorBase<"a", [{
252   $region attr-dict
253 }]>;
255 // Test various mixings of result type formatting.
256 class FormatResultBase<string suffix, string fmt>
257     : TEST_Op<"format_result_" # suffix # "_op"> {
258   let results = (outs I64:$buildable_res, AnyMemRef:$result);
259   let assemblyFormat = fmt;
261 def FormatResultAOp : FormatResultBase<"a", [{
262   type($result) attr-dict
263 }]>;
264 def FormatResultBOp : FormatResultBase<"b", [{
265   type(results) attr-dict
266 }]>;
267 def FormatResultCOp : FormatResultBase<"c", [{
268   functional-type($buildable_res, $result) attr-dict
269 }]>;
271 def FormatVariadicResult : TEST_Op<"format_variadic_result"> {
272   let results = (outs Variadic<I64>:$result);
273   let assemblyFormat = [{ `:` type($result) attr-dict}];
276 def FormatMultipleVariadicResults : TEST_Op<"format_multiple_variadic_results",
277                                             [AttrSizedResultSegments]> {
278   let results = (outs Variadic<I64>:$result0, Variadic<AnyType>:$result1);
279   let assemblyFormat = [{
280     `:` `(` type($result0) `)` `,` `(` type($result1) `)` attr-dict
281   }];
284 // Test various mixings of operand type formatting.
285 class FormatOperandBase<string suffix, string fmt>
286     : TEST_Op<"format_operand_" # suffix # "_op"> {
287   let arguments = (ins I64:$buildable, AnyMemRef:$operand);
288   let assemblyFormat = fmt;
291 def FormatOperandAOp : FormatOperandBase<"a", [{
292   operands `:` type(operands) attr-dict
293 }]>;
294 def FormatOperandBOp : FormatOperandBase<"b", [{
295   operands `:` type($operand) attr-dict
296 }]>;
297 def FormatOperandCOp : FormatOperandBase<"c", [{
298   $buildable `,` $operand `:` type(operands) attr-dict
299 }]>;
300 def FormatOperandDOp : FormatOperandBase<"d", [{
301   $buildable `,` $operand `:` type($operand) attr-dict
302 }]>;
303 def FormatOperandEOp : FormatOperandBase<"e", [{
304   $buildable `,` $operand `:` type($buildable) `,` type($operand) attr-dict
305 }]>;
307 def FormatSuccessorAOp : TEST_Op<"format_successor_a_op", [Terminator]> {
308   let successors = (successor VariadicSuccessor<AnySuccessor>:$targets);
309   let assemblyFormat = "$targets attr-dict";
312 def FormatVariadicOperand : TEST_Op<"format_variadic_operand"> {
313   let arguments = (ins Variadic<I64>:$operand);
314   let assemblyFormat = [{ $operand `:` type($operand) attr-dict}];
316 def FormatVariadicOfVariadicOperand
317    : TEST_Op<"format_variadic_of_variadic_operand"> {
318   let arguments = (ins
319     VariadicOfVariadic<I64, "operand_segments">:$operand,
320     DenseI32ArrayAttr:$operand_segments
321   );
322   let assemblyFormat = [{ $operand `:` type($operand) attr-dict}];
325 def FormatMultipleVariadicOperands :
326     TEST_Op<"format_multiple_variadic_operands", [AttrSizedOperandSegments]> {
327   let arguments = (ins Variadic<I64>:$operand0, Variadic<AnyType>:$operand1);
328   let assemblyFormat = [{
329     ` ` `(` $operand0 `)` `,` `(` $operand1 `:` type($operand1) `)` attr-dict
330   }];
333 // Test various mixings of optional operand and result type formatting.
334 class FormatOptionalOperandResultOpBase<string suffix, string fmt>
335     : TEST_Op<"format_optional_operand_result_" # suffix # "_op",
336               [AttrSizedOperandSegments]> {
337   let arguments = (ins Optional<I64>:$optional, Variadic<I64>:$variadic);
338   let results = (outs Optional<I64>:$optional_res);
339   let assemblyFormat = fmt;
342 def FormatOptionalOperandResultAOp : FormatOptionalOperandResultOpBase<"a", [{
343   `(` $optional `:` type($optional) `)` `:` type($optional_res)
344   (`[` $variadic^ `]`)? attr-dict
345 }]>;
347 def FormatOptionalOperandResultBOp : FormatOptionalOperandResultOpBase<"b", [{
348   (`(` $optional^ `:` type($optional) `)`)? `:` type($optional_res)
349   (`[` $variadic^ `]`)? attr-dict
350 }]>;
352 // Test optional result type formatting.
353 class FormatOptionalResultOpBase<string suffix, string fmt>
354     : TEST_Op<"format_optional_result_" # suffix # "_op",
355               [AttrSizedResultSegments]> {
356   let results = (outs Optional<I64>:$optional, Variadic<I64>:$variadic);
357   let assemblyFormat = fmt;
359 def FormatOptionalResultAOp : FormatOptionalResultOpBase<"a", [{
360   (`:` type($optional)^ `->` type($variadic))? attr-dict
361 }]>;
363 def FormatOptionalResultBOp : FormatOptionalResultOpBase<"b", [{
364   (`:` type($optional) `->` type($variadic)^)? attr-dict
365 }]>;
367 def FormatOptionalResultCOp : FormatOptionalResultOpBase<"c", [{
368   (`:` functional-type($optional, $variadic)^)? attr-dict
369 }]>;
371 def FormatOptionalResultDOp
372   : TEST_Op<"format_optional_result_d_op" > {
373   let results = (outs Optional<F80>:$optional);
374   let assemblyFormat = "(`:` type($optional)^)? attr-dict";
377 def FormatTwoVariadicOperandsNoBuildableTypeOp
378     : TEST_Op<"format_two_variadic_operands_no_buildable_type_op",
379               [AttrSizedOperandSegments]> {
380   let arguments = (ins Variadic<AnyType>:$a,
381                        Variadic<AnyType>:$b);
382   let assemblyFormat = [{
383     `(` $a `:` type($a) `)` `->` `(` $b `:` type($b) `)`  attr-dict
384   }];
387 def FormatInferVariadicTypeFromNonVariadic
388     : TEST_Op<"format_infer_variadic_type_from_non_variadic",
389               [SameOperandsAndResultType]> {
390   let arguments = (ins Variadic<AnyType>:$args);
391   let results = (outs AnyType:$result);
392   let assemblyFormat = "operands attr-dict `:` type($result)";
395 def FormatOptionalUnitAttr : TEST_Op<"format_optional_unit_attribute"> {
396   let arguments = (ins UnitAttr:$is_optional);
397   let assemblyFormat = "(`is_optional` $is_optional^)? attr-dict";
400 def FormatOptionalUnitAttrNoElide
401     : TEST_Op<"format_optional_unit_attribute_no_elide"> {
402   let arguments = (ins UnitAttr:$is_optional);
403   let assemblyFormat = "($is_optional^)? attr-dict";
406 def FormatOptionalUnitProperty : TEST_Op<"format_optional_unit_property"> {
407   let arguments = (ins UnitProperty:$is_optional);
408   let assemblyFormat = "(`is_optional` $is_optional^)? attr-dict";
411 def FormatOptionalUnitPropertyNoElide
412     : TEST_Op<"format_optional_unit_property_no_elide"> {
413   let arguments = (ins UnitProperty:$is_optional);
414   let assemblyFormat = "($is_optional^)? attr-dict";
417 def FormatOptionalEnumAttr : TEST_Op<"format_optional_enum_attr"> {
418   let arguments = (ins OptionalAttr<SomeI64Enum>:$attr);
419   let assemblyFormat = "($attr^)? attr-dict";
422 def FormatOptionalDefaultAttrs : TEST_Op<"format_optional_default_attrs"> {
423   let arguments = (ins DefaultValuedStrAttr<StrAttr, "default">:$str,
424                        DefaultValuedStrAttr<SymbolNameAttr, "default">:$sym,
425                        DefaultValuedAttr<SomeI64Enum, "SomeI64Enum::case5">:$e);
426   let assemblyFormat = "($str^)? ($sym^)? ($e^)? attr-dict";
429 def FormatOptionalWithElse : TEST_Op<"format_optional_else"> {
430   let arguments = (ins UnitAttr:$isFirstBranchPresent);
431   let assemblyFormat = "(`then` $isFirstBranchPresent^):(`else`)? attr-dict";
434 def FormatCompoundAttr : TEST_Op<"format_compound_attr"> {
435   let arguments = (ins CompoundAttrA:$compound);
436   let assemblyFormat = "$compound attr-dict-with-keyword";
439 def FormatNestedAttr : TEST_Op<"format_nested_attr"> {
440   let arguments = (ins CompoundAttrNested:$nested);
441   let assemblyFormat = "$nested attr-dict-with-keyword";
444 def FormatNestedCompoundAttr : TEST_Op<"format_cpmd_nested_attr"> {
445   let arguments = (ins CompoundNestedOuter:$nested);
446   let assemblyFormat = "`nested` $nested attr-dict-with-keyword";
449 def FormatMaybeEmptyType : TEST_Op<"format_maybe_empty_type"> {
450   let arguments = (ins TestTypeOptionalValueType:$in);
451   let assemblyFormat = "$in `:` type($in) attr-dict";
454 def FormatQualifiedCompoundAttr : TEST_Op<"format_qual_cpmd_nested_attr"> {
455   let arguments = (ins CompoundNestedOuter:$nested);
456   let assemblyFormat = "`nested` qualified($nested) attr-dict-with-keyword";
459 def FormatNestedType : TEST_Op<"format_cpmd_nested_type"> {
460   let arguments = (ins CompoundNestedOuterType:$nested);
461   let assemblyFormat = "$nested `nested` type($nested) attr-dict-with-keyword";
464 def FormatQualifiedNestedType : TEST_Op<"format_qual_cpmd_nested_type"> {
465   let arguments = (ins CompoundNestedOuterType:$nested);
466   let assemblyFormat = "$nested `nested` qualified(type($nested)) attr-dict-with-keyword";
469 //===----------------------------------------------------------------------===//
470 // Custom Directives
472 def FormatCustomDirectiveOperands
473     : TEST_Op<"format_custom_directive_operands", [AttrSizedOperandSegments]> {
474   let arguments = (ins I64:$operand, Optional<I64>:$optOperand,
475                        Variadic<I64>:$varOperands);
476   let assemblyFormat = [{
477     custom<CustomDirectiveOperands>(
478       $operand, $optOperand, $varOperands
479     )
480     attr-dict
481   }];
484 def FormatCustomDirectiveOperandsAndTypes
485     : TEST_Op<"format_custom_directive_operands_and_types",
486               [AttrSizedOperandSegments]> {
487   let arguments = (ins AnyType:$operand, Optional<AnyType>:$optOperand,
488                        Variadic<AnyType>:$varOperands);
489   let assemblyFormat = [{
490     custom<CustomDirectiveOperandsAndTypes>(
491       $operand, $optOperand, $varOperands,
492       type($operand), type($optOperand), type($varOperands)
493     )
494     attr-dict
495   }];
498 def FormatCustomDirectiveRegions : TEST_Op<"format_custom_directive_regions"> {
499   let regions = (region AnyRegion:$region, VariadicRegion<AnyRegion>:$other_regions);
500   let assemblyFormat = [{
501     custom<CustomDirectiveRegions>(
502       $region, $other_regions
503     )
504     attr-dict
505   }];
508 def FormatCustomDirectiveResults
509     : TEST_Op<"format_custom_directive_results", [AttrSizedResultSegments]> {
510   let results = (outs AnyType:$result, Optional<AnyType>:$optResult,
511                       Variadic<AnyType>:$varResults);
512   let assemblyFormat = [{
513     custom<CustomDirectiveResults>(
514       type($result), type($optResult), type($varResults)
515     )
516     attr-dict
517   }];
520 def FormatCustomDirectiveResultsWithTypeRefs
521     : TEST_Op<"format_custom_directive_results_with_type_refs",
522               [AttrSizedResultSegments]> {
523   let results = (outs AnyType:$result, Optional<AnyType>:$optResult,
524                       Variadic<AnyType>:$varResults);
525   let assemblyFormat = [{
526     custom<CustomDirectiveResults>(
527       type($result), type($optResult), type($varResults)
528     )
529     custom<CustomDirectiveWithTypeRefs>(
530       ref(type($result)), ref(type($optResult)), ref(type($varResults))
531     )
532     attr-dict
533   }];
536 def FormatCustomDirectiveWithOptionalOperandRef
537     : TEST_Op<"format_custom_directive_with_optional_operand_ref"> {
538   let arguments = (ins Optional<I64>:$optOperand);
539   let assemblyFormat = [{
540     ($optOperand^)? `:`
541     custom<CustomDirectiveOptionalOperandRef>(ref($optOperand))
542     attr-dict
543   }];
546 def FormatCustomDirectiveSuccessors
547     : TEST_Op<"format_custom_directive_successors", [Terminator]> {
548   let successors = (successor AnySuccessor:$successor,
549                               VariadicSuccessor<AnySuccessor>:$successors);
550   let assemblyFormat = [{
551     custom<CustomDirectiveSuccessors>(
552       $successor, $successors
553     )
554     attr-dict
555   }];
558 def FormatCustomDirectiveAttributes
559     : TEST_Op<"format_custom_directive_attributes"> {
560   let arguments = (ins I64Attr:$attr, OptionalAttr<I64Attr>:$optAttr);
561   let assemblyFormat = [{
562     custom<CustomDirectiveAttributes>(
563       $attr, $optAttr
564     )
565     attr-dict
566   }];
569 def FormatCustomDirectiveSpacing
570     : TEST_Op<"format_custom_directive_spacing"> {
571   let arguments = (ins StrAttr:$attr1, StrAttr:$attr2);
572   let assemblyFormat = [{
573     custom<CustomDirectiveSpacing>($attr1)
574     custom<CustomDirectiveSpacing>($attr2)
575     attr-dict
576   }];
579 def FormatCustomDirectiveAttrDict
580     : TEST_Op<"format_custom_directive_attrdict"> {
581   let arguments = (ins I64Attr:$attr, OptionalAttr<I64Attr>:$optAttr);
582   let assemblyFormat = [{
583     custom<CustomDirectiveAttrDict>( attr-dict )
584   }];
587 def FormatLiteralFollowingOptionalGroup
588     : TEST_Op<"format_literal_following_optional_group"> {
589   let arguments = (ins TypeAttr:$type, OptionalAttr<AnyAttr>:$value);
590   let assemblyFormat = "(`(` $value^ `)`)? `:` $type attr-dict";
593 //===----------------------------------------------------------------------===//
594 // AllTypesMatch type inference
596 def FormatAllTypesMatchVarOp : TEST_Op<"format_all_types_match_var", [
597     AllTypesMatch<["value1", "value2", "result"]>
598   ]> {
599   let arguments = (ins AnyType:$value1, AnyType:$value2);
600   let results = (outs AnyType:$result);
601   let assemblyFormat = "attr-dict $value1 `,` $value2 `:` type($value1)";
604 def FormatAllTypesMatchAttrOp : TEST_Op<"format_all_types_match_attr", [
605     AllTypesMatch<["value1", "value2", "result"]>
606   ]> {
607   let arguments = (ins TypedAttrInterface:$value1, AnyType:$value2);
608   let results = (outs AnyType:$result);
609   let assemblyFormat = "attr-dict $value1 `,` $value2";
612 //===----------------------------------------------------------------------===//
613 // TypesMatchWith type inference
615 def FormatTypesMatchVarOp : TEST_Op<"format_types_match_var", [
616     TypesMatchWith<"result type matches operand", "value", "result", "$_self">
617   ]> {
618   let arguments = (ins AnyType:$value);
619   let results = (outs AnyType:$result);
620   let assemblyFormat = "attr-dict $value `:` type($value)";
623 def FormatTypesMatchVariadicOp : TEST_Op<"format_types_match_variadic", [
624     RangedTypesMatchWith<"result type matches operand", "value", "result",
625                          "llvm::make_range($_self.begin(), $_self.end())">
626   ]> {
627   let arguments = (ins Variadic<AnyType>:$value);
628   let results = (outs Variadic<AnyType>:$result);
629   let assemblyFormat = "attr-dict $value `:` type($value)";
632 def FormatTypesMatchAttrOp : TEST_Op<"format_types_match_attr", [
633     TypesMatchWith<"result type matches constant", "value", "result", "$_self">
634   ]> {
635   let arguments = (ins TypedAttrInterface:$value);
636   let results = (outs AnyType:$result);
637   let assemblyFormat = "attr-dict $value";
640 def FormatTypesMatchContextOp : TEST_Op<"format_types_match_context", [
641     TypesMatchWith<"tuple result type matches operand type", "value", "result",
642         "::mlir::TupleType::get($_ctxt, $_self)">
643   ]> {
644   let arguments = (ins AnyType:$value);
645   let results = (outs AnyType:$result);
646   let assemblyFormat = "attr-dict $value `:` type($value)";
649 //===----------------------------------------------------------------------===//
650 // InferTypeOpInterface type inference in assembly format
652 def FormatInferTypeOp : TEST_Op<"format_infer_type", [InferTypeOpInterface]> {
653   let results = (outs AnyType);
654   let assemblyFormat = "attr-dict";
656   let extraClassDeclaration = [{
657     static ::llvm::LogicalResult inferReturnTypes(::mlir::MLIRContext *context,
658           ::std::optional<::mlir::Location> location, ::mlir::ValueRange operands,
659           ::mlir::DictionaryAttr attributes, mlir::OpaqueProperties properties, ::mlir::RegionRange regions,
660           ::llvm::SmallVectorImpl<::mlir::Type> &inferredReturnTypes) {
661       inferredReturnTypes.assign({::mlir::IntegerType::get(context, 16)});
662       return ::mlir::success();
663     }
664    }];
667 // Check that formatget supports DeclareOpInterfaceMethods.
668 def FormatInferType2Op : TEST_Op<"format_infer_type2", [DeclareOpInterfaceMethods<InferTypeOpInterface>]> {
669   let results = (outs AnyType);
670   let assemblyFormat = "attr-dict";
673 // Base class for testing mixing allOperandTypes, allOperands, and
674 // inferResultTypes.
675 class FormatInferAllTypesBaseOp<string mnemonic, list<Trait> traits = []>
676     : TEST_Op<mnemonic, [InferTypeOpInterface] # traits> {
677   let arguments = (ins Variadic<AnyType>:$args);
678   let results = (outs Variadic<AnyType>:$outs);
679   let extraClassDeclaration = [{
680     static ::llvm::LogicalResult inferReturnTypes(::mlir::MLIRContext *context,
681           ::std::optional<::mlir::Location> location, ::mlir::ValueRange operands,
682           ::mlir::DictionaryAttr attributes, mlir::OpaqueProperties properties, ::mlir::RegionRange regions,
683           ::llvm::SmallVectorImpl<::mlir::Type> &inferredReturnTypes) {
684       ::mlir::TypeRange operandTypes = operands.getTypes();
685       inferredReturnTypes.assign(operandTypes.begin(), operandTypes.end());
686       return ::mlir::success();
687     }
688    }];
691 // Test inferReturnTypes is called when allOperandTypes and allOperands is true.
692 def FormatInferTypeAllOperandsAndTypesOp
693     : FormatInferAllTypesBaseOp<"format_infer_type_all_operands_and_types"> {
694   let assemblyFormat = "`(` operands `)` attr-dict `:` type(operands)";
697 // Test inferReturnTypes is called when allOperandTypes is true and there is one
698 // ODS operand.
699 def FormatInferTypeAllOperandsAndTypesOneOperandOp
700     : FormatInferAllTypesBaseOp<"format_infer_type_all_types_one_operand"> {
701   let assemblyFormat = "`(` $args `)` attr-dict `:` type(operands)";
704 // Test inferReturnTypes is called when allOperandTypes is true and there are
705 // more than one ODS operands.
706 def FormatInferTypeAllOperandsAndTypesTwoOperandsOp
707     : FormatInferAllTypesBaseOp<"format_infer_type_all_types_two_operands",
708                                 [SameVariadicOperandSize]> {
709   let arguments = (ins Variadic<AnyType>:$args0, Variadic<AnyType>:$args1);
710   let assemblyFormat = "`(` $args0 `)` `(` $args1 `)` attr-dict `:` type(operands)";
713 // Test inferReturnTypes is called when allOperands is true and operand types
714 // are separately specified.
715 def FormatInferTypeAllTypesOp
716     : FormatInferAllTypesBaseOp<"format_infer_type_all_types"> {
717   let assemblyFormat = "`(` operands `)` attr-dict `:` type($args)";
720 // Test inferReturnTypes coupled with regions.
721 def FormatInferTypeRegionsOp
722     : TEST_Op<"format_infer_type_regions", [InferTypeOpInterface]> {
723   let results = (outs Variadic<AnyType>:$outs);
724   let regions = (region AnyRegion:$region);
725   let assemblyFormat = "$region attr-dict";
726   let extraClassDeclaration = [{
727     static ::llvm::LogicalResult inferReturnTypes(::mlir::MLIRContext *context,
728           ::std::optional<::mlir::Location> location, ::mlir::ValueRange operands,
729           ::mlir::DictionaryAttr attributes, mlir::OpaqueProperties properties, ::mlir::RegionRange regions,
730           ::llvm::SmallVectorImpl<::mlir::Type> &inferredReturnTypes) {
731       if (regions.empty())
732         return ::mlir::failure();
733       auto types = regions.front()->getArgumentTypes();
734       inferredReturnTypes.assign(types.begin(), types.end());
735       return ::mlir::success();
736     }
737   }];
740 // Test inferReturnTypes coupled with variadic operands (operandSegmentSizes).
741 def FormatInferTypeVariadicOperandsOp
742     : TEST_Op<"format_infer_type_variadic_operands",
743               [InferTypeOpInterface, AttrSizedOperandSegments]> {
744   let arguments = (ins Variadic<I32>:$a, Variadic<I64>:$b);
745   let results = (outs Variadic<AnyType>:$outs);
746   let assemblyFormat = "`(` $a `:` type($a) `)` `(` $b `:` type($b) `)` attr-dict";
747   let extraClassDeclaration = [{
748     static ::llvm::LogicalResult inferReturnTypes(::mlir::MLIRContext *context,
749           ::std::optional<::mlir::Location> location, ::mlir::ValueRange operands,
750           ::mlir::DictionaryAttr attributes, mlir::OpaqueProperties properties, ::mlir::RegionRange regions,
751           ::llvm::SmallVectorImpl<::mlir::Type> &inferredReturnTypes) {
752       FormatInferTypeVariadicOperandsOpAdaptor adaptor(
753           operands, attributes, *properties.as<Properties *>(), {});
754       auto aTypes = adaptor.getA().getTypes();
755       auto bTypes = adaptor.getB().getTypes();
756       inferredReturnTypes.append(aTypes.begin(), aTypes.end());
757       inferredReturnTypes.append(bTypes.begin(), bTypes.end());
758       return ::mlir::success();
759     }
760   }];
763 #endif  // TEST_OPS_SYNTAX