2 //===-- TestOpsSyntax.td - Operations for testing syntax ---*- tablegen -*-===//
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
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";
26 Test op wrapping another op in a region, to test calling
27 parseGenericOperation from the custom parser.
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";
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.
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";
56 Test op with multiple region arguments, each argument of index type.
58 let extraClassDeclaration = [{
59 void getAsmBlockArgumentNames(mlir::Region ®ion,
60 mlir::OpAsmSetValueNameFn setNameFn);
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";
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
89 // Ops related to OIList primitive
90 def OIListTrivialProperties : TEST_Op<"oilist_with_keywords_only_properties"> {
91 let arguments = (ins UnitProp:$keyword, UnitProp:$otherKeyword,
92 UnitProp:$diffNameUnitPropKeyword);
93 let assemblyFormat = [{
94 oilist( `keyword` $keyword
95 | `otherKeyword` $otherKeyword
96 | `thirdKeyword` $diffNameUnitPropKeyword) attr-dict
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
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
122 def OIListCustom : TEST_Op<"oilist_custom", [AttrSizedOperandSegments]> {
123 let arguments = (ins Variadic<AnyType>:$arg0,
124 Optional<I32>:$optOperand,
126 let assemblyFormat = [{
127 oilist( `private` `(` $arg0 `:` type($arg0) `)`
128 | `reduction` custom<CustomOptionalOperand>($optOperand)
134 def OIListAllowedLiteral : TEST_Op<"oilist_allowed_literal"> {
135 let assemblyFormat = [{
136 oilist( `foo` | `bar` ) `buzz` attr-dict
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) `...`
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";
160 //===----------------------------------------------------------------------===//
161 // Test Op Asm Format
162 //===----------------------------------------------------------------------===//
164 def FormatLiteralOp : TEST_Op<"format_literal_op"> {
165 let assemblyFormat = [{
166 `keyword_$.` `->` `:` `,` `=` `<` `>` `(` `)` `[` `]` `` `(` ` ` `)`
167 `?` `+` `*` `{` `\n` `}` attr-dict
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", [{
227 def FormatRegionBOp : FormatRegionBase<"b", [{
230 def FormatRegionCOp : FormatRegionBase<"c", [{
231 (`region` $region^)? attr-dict
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", [{
241 def FormatVariadicRegionBOp : FormatVariadicRegionBase<"b", [{
242 ($regions^ `found_regions`)? attr-dict
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", [{
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
264 def FormatResultBOp : FormatResultBase<"b", [{
265 type(results) attr-dict
267 def FormatResultCOp : FormatResultBase<"c", [{
268 functional-type($buildable_res, $result) attr-dict
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
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
294 def FormatOperandBOp : FormatOperandBase<"b", [{
295 operands `:` type($operand) attr-dict
297 def FormatOperandCOp : FormatOperandBase<"c", [{
298 $buildable `,` $operand `:` type(operands) attr-dict
300 def FormatOperandDOp : FormatOperandBase<"d", [{
301 $buildable `,` $operand `:` type($operand) attr-dict
303 def FormatOperandEOp : FormatOperandBase<"e", [{
304 $buildable `,` $operand `:` type($buildable) `,` type($operand) attr-dict
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"> {
319 VariadicOfVariadic<I64, "operand_segments">:$operand,
320 DenseI32ArrayAttr:$operand_segments
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
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
347 def FormatOptionalOperandResultBOp : FormatOptionalOperandResultOpBase<"b", [{
348 (`(` $optional^ `:` type($optional) `)`)? `:` type($optional_res)
349 (`[` $variadic^ `]`)? attr-dict
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
363 def FormatOptionalResultBOp : FormatOptionalResultOpBase<"b", [{
364 (`:` type($optional) `->` type($variadic)^)? attr-dict
367 def FormatOptionalResultCOp : FormatOptionalResultOpBase<"c", [{
368 (`:` functional-type($optional, $variadic)^)? attr-dict
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
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 UnitProp:$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 UnitProp:$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 FormatOptionalPropDict : TEST_Op<"format_optional_prop_dict"> {
436 OptionalProp<StringProp>:$a,
437 DefaultValuedProp<I32Prop, "1">:$b);
438 let assemblyFormat = "prop-dict attr-dict";
441 def FormatCompoundAttr : TEST_Op<"format_compound_attr"> {
442 let arguments = (ins CompoundAttrA:$compound);
443 let assemblyFormat = "$compound attr-dict-with-keyword";
446 def FormatNestedAttr : TEST_Op<"format_nested_attr"> {
447 let arguments = (ins CompoundAttrNested:$nested);
448 let assemblyFormat = "$nested attr-dict-with-keyword";
451 def FormatNestedCompoundAttr : TEST_Op<"format_cpmd_nested_attr"> {
452 let arguments = (ins CompoundNestedOuter:$nested);
453 let assemblyFormat = "`nested` $nested attr-dict-with-keyword";
456 def FormatMaybeEmptyType : TEST_Op<"format_maybe_empty_type"> {
457 let arguments = (ins TestTypeOptionalValueType:$in);
458 let assemblyFormat = "$in `:` type($in) attr-dict";
461 def FormatQualifiedCompoundAttr : TEST_Op<"format_qual_cpmd_nested_attr"> {
462 let arguments = (ins CompoundNestedOuter:$nested);
463 let assemblyFormat = "`nested` qualified($nested) attr-dict-with-keyword";
466 def FormatNestedType : TEST_Op<"format_cpmd_nested_type"> {
467 let arguments = (ins CompoundNestedOuterType:$nested);
468 let assemblyFormat = "$nested `nested` type($nested) attr-dict-with-keyword";
471 def FormatQualifiedNestedType : TEST_Op<"format_qual_cpmd_nested_type"> {
472 let arguments = (ins CompoundNestedOuterType:$nested);
473 let assemblyFormat = "$nested `nested` qualified(type($nested)) attr-dict-with-keyword";
476 //===----------------------------------------------------------------------===//
479 def FormatCustomDirectiveOperands
480 : TEST_Op<"format_custom_directive_operands", [AttrSizedOperandSegments]> {
481 let arguments = (ins I64:$operand, Optional<I64>:$optOperand,
482 Variadic<I64>:$varOperands);
483 let assemblyFormat = [{
484 custom<CustomDirectiveOperands>(
485 $operand, $optOperand, $varOperands
491 def FormatCustomDirectiveOperandsAndTypes
492 : TEST_Op<"format_custom_directive_operands_and_types",
493 [AttrSizedOperandSegments]> {
494 let arguments = (ins AnyType:$operand, Optional<AnyType>:$optOperand,
495 Variadic<AnyType>:$varOperands);
496 let assemblyFormat = [{
497 custom<CustomDirectiveOperandsAndTypes>(
498 $operand, $optOperand, $varOperands,
499 type($operand), type($optOperand), type($varOperands)
505 def FormatCustomDirectiveRegions : TEST_Op<"format_custom_directive_regions"> {
506 let regions = (region AnyRegion:$region, VariadicRegion<AnyRegion>:$other_regions);
507 let assemblyFormat = [{
508 custom<CustomDirectiveRegions>(
509 $region, $other_regions
515 def FormatCustomDirectiveResults
516 : TEST_Op<"format_custom_directive_results", [AttrSizedResultSegments]> {
517 let results = (outs AnyType:$result, Optional<AnyType>:$optResult,
518 Variadic<AnyType>:$varResults);
519 let assemblyFormat = [{
520 custom<CustomDirectiveResults>(
521 type($result), type($optResult), type($varResults)
527 def FormatCustomDirectiveResultsWithTypeRefs
528 : TEST_Op<"format_custom_directive_results_with_type_refs",
529 [AttrSizedResultSegments]> {
530 let results = (outs AnyType:$result, Optional<AnyType>:$optResult,
531 Variadic<AnyType>:$varResults);
532 let assemblyFormat = [{
533 custom<CustomDirectiveResults>(
534 type($result), type($optResult), type($varResults)
536 custom<CustomDirectiveWithTypeRefs>(
537 ref(type($result)), ref(type($optResult)), ref(type($varResults))
543 def FormatCustomDirectiveWithOptionalOperandRef
544 : TEST_Op<"format_custom_directive_with_optional_operand_ref"> {
545 let arguments = (ins Optional<I64>:$optOperand);
546 let assemblyFormat = [{
548 custom<CustomDirectiveOptionalOperandRef>(ref($optOperand))
553 def FormatCustomDirectiveSuccessors
554 : TEST_Op<"format_custom_directive_successors", [Terminator]> {
555 let successors = (successor AnySuccessor:$successor,
556 VariadicSuccessor<AnySuccessor>:$successors);
557 let assemblyFormat = [{
558 custom<CustomDirectiveSuccessors>(
559 $successor, $successors
565 def FormatCustomDirectiveAttributes
566 : TEST_Op<"format_custom_directive_attributes"> {
567 let arguments = (ins I64Attr:$attr, OptionalAttr<I64Attr>:$optAttr);
568 let assemblyFormat = [{
569 custom<CustomDirectiveAttributes>(
576 def FormatCustomDirectiveSpacing
577 : TEST_Op<"format_custom_directive_spacing"> {
578 let arguments = (ins StrAttr:$attr1, StrAttr:$attr2);
579 let assemblyFormat = [{
580 custom<CustomDirectiveSpacing>($attr1)
581 custom<CustomDirectiveSpacing>($attr2)
586 def FormatCustomDirectiveAttrDict
587 : TEST_Op<"format_custom_directive_attrdict"> {
588 let arguments = (ins I64Attr:$attr, OptionalAttr<I64Attr>:$optAttr);
589 let assemblyFormat = [{
590 custom<CustomDirectiveAttrDict>( attr-dict )
594 def FormatLiteralFollowingOptionalGroup
595 : TEST_Op<"format_literal_following_optional_group"> {
596 let arguments = (ins TypeAttr:$type, OptionalAttr<AnyAttr>:$value);
597 let assemblyFormat = "(`(` $value^ `)`)? `:` $type attr-dict";
600 //===----------------------------------------------------------------------===//
601 // AllTypesMatch type inference
603 def FormatAllTypesMatchVarOp : TEST_Op<"format_all_types_match_var", [
604 AllTypesMatch<["value1", "value2", "result"]>
606 let arguments = (ins AnyType:$value1, AnyType:$value2);
607 let results = (outs AnyType:$result);
608 let assemblyFormat = "attr-dict $value1 `,` $value2 `:` type($value1)";
611 def FormatAllTypesMatchAttrOp : TEST_Op<"format_all_types_match_attr", [
612 AllTypesMatch<["value1", "value2", "result"]>
614 let arguments = (ins TypedAttrInterface:$value1, AnyType:$value2);
615 let results = (outs AnyType:$result);
616 let assemblyFormat = "attr-dict $value1 `,` $value2";
619 //===----------------------------------------------------------------------===//
620 // TypesMatchWith type inference
622 def FormatTypesMatchVarOp : TEST_Op<"format_types_match_var", [
623 TypesMatchWith<"result type matches operand", "value", "result", "$_self">
625 let arguments = (ins AnyType:$value);
626 let results = (outs AnyType:$result);
627 let assemblyFormat = "attr-dict $value `:` type($value)";
630 def FormatTypesMatchVariadicOp : TEST_Op<"format_types_match_variadic", [
631 RangedTypesMatchWith<"result type matches operand", "value", "result",
632 "llvm::make_range($_self.begin(), $_self.end())">
634 let arguments = (ins Variadic<AnyType>:$value);
635 let results = (outs Variadic<AnyType>:$result);
636 let assemblyFormat = "attr-dict $value `:` type($value)";
639 def FormatTypesMatchAttrOp : TEST_Op<"format_types_match_attr", [
640 TypesMatchWith<"result type matches constant", "value", "result", "$_self">
642 let arguments = (ins TypedAttrInterface:$value);
643 let results = (outs AnyType:$result);
644 let assemblyFormat = "attr-dict $value";
647 def FormatTypesMatchContextOp : TEST_Op<"format_types_match_context", [
648 TypesMatchWith<"tuple result type matches operand type", "value", "result",
649 "::mlir::TupleType::get($_ctxt, $_self)">
651 let arguments = (ins AnyType:$value);
652 let results = (outs AnyType:$result);
653 let assemblyFormat = "attr-dict $value `:` type($value)";
656 //===----------------------------------------------------------------------===//
657 // InferTypeOpInterface type inference in assembly format
659 def FormatInferTypeOp : TEST_Op<"format_infer_type", [InferTypeOpInterface]> {
660 let results = (outs AnyType);
661 let assemblyFormat = "attr-dict";
663 let extraClassDeclaration = [{
664 static ::llvm::LogicalResult inferReturnTypes(::mlir::MLIRContext *context,
665 ::std::optional<::mlir::Location> location, ::mlir::ValueRange operands,
666 ::mlir::DictionaryAttr attributes, mlir::OpaqueProperties properties, ::mlir::RegionRange regions,
667 ::llvm::SmallVectorImpl<::mlir::Type> &inferredReturnTypes) {
668 inferredReturnTypes.assign({::mlir::IntegerType::get(context, 16)});
669 return ::mlir::success();
674 // Check that formatget supports DeclareOpInterfaceMethods.
675 def FormatInferType2Op : TEST_Op<"format_infer_type2", [DeclareOpInterfaceMethods<InferTypeOpInterface>]> {
676 let results = (outs AnyType);
677 let assemblyFormat = "attr-dict";
680 // Base class for testing mixing allOperandTypes, allOperands, and
682 class FormatInferAllTypesBaseOp<string mnemonic, list<Trait> traits = []>
683 : TEST_Op<mnemonic, [InferTypeOpInterface] # traits> {
684 let arguments = (ins Variadic<AnyType>:$args);
685 let results = (outs Variadic<AnyType>:$outs);
686 let extraClassDeclaration = [{
687 static ::llvm::LogicalResult inferReturnTypes(::mlir::MLIRContext *context,
688 ::std::optional<::mlir::Location> location, ::mlir::ValueRange operands,
689 ::mlir::DictionaryAttr attributes, mlir::OpaqueProperties properties, ::mlir::RegionRange regions,
690 ::llvm::SmallVectorImpl<::mlir::Type> &inferredReturnTypes) {
691 ::mlir::TypeRange operandTypes = operands.getTypes();
692 inferredReturnTypes.assign(operandTypes.begin(), operandTypes.end());
693 return ::mlir::success();
698 // Test inferReturnTypes is called when allOperandTypes and allOperands is true.
699 def FormatInferTypeAllOperandsAndTypesOp
700 : FormatInferAllTypesBaseOp<"format_infer_type_all_operands_and_types"> {
701 let assemblyFormat = "`(` operands `)` attr-dict `:` type(operands)";
704 // Test inferReturnTypes is called when allOperandTypes is true and there is one
706 def FormatInferTypeAllOperandsAndTypesOneOperandOp
707 : FormatInferAllTypesBaseOp<"format_infer_type_all_types_one_operand"> {
708 let assemblyFormat = "`(` $args `)` attr-dict `:` type(operands)";
711 // Test inferReturnTypes is called when allOperandTypes is true and there are
712 // more than one ODS operands.
713 def FormatInferTypeAllOperandsAndTypesTwoOperandsOp
714 : FormatInferAllTypesBaseOp<"format_infer_type_all_types_two_operands",
715 [SameVariadicOperandSize]> {
716 let arguments = (ins Variadic<AnyType>:$args0, Variadic<AnyType>:$args1);
717 let assemblyFormat = "`(` $args0 `)` `(` $args1 `)` attr-dict `:` type(operands)";
720 // Test inferReturnTypes is called when allOperands is true and operand types
721 // are separately specified.
722 def FormatInferTypeAllTypesOp
723 : FormatInferAllTypesBaseOp<"format_infer_type_all_types"> {
724 let assemblyFormat = "`(` operands `)` attr-dict `:` type($args)";
727 // Test inferReturnTypes coupled with regions.
728 def FormatInferTypeRegionsOp
729 : TEST_Op<"format_infer_type_regions", [InferTypeOpInterface]> {
730 let results = (outs Variadic<AnyType>:$outs);
731 let regions = (region AnyRegion:$region);
732 let assemblyFormat = "$region attr-dict";
733 let extraClassDeclaration = [{
734 static ::llvm::LogicalResult inferReturnTypes(::mlir::MLIRContext *context,
735 ::std::optional<::mlir::Location> location, ::mlir::ValueRange operands,
736 ::mlir::DictionaryAttr attributes, mlir::OpaqueProperties properties, ::mlir::RegionRange regions,
737 ::llvm::SmallVectorImpl<::mlir::Type> &inferredReturnTypes) {
739 return ::mlir::failure();
740 auto types = regions.front()->getArgumentTypes();
741 inferredReturnTypes.assign(types.begin(), types.end());
742 return ::mlir::success();
747 // Test inferReturnTypes coupled with variadic operands (operandSegmentSizes).
748 def FormatInferTypeVariadicOperandsOp
749 : TEST_Op<"format_infer_type_variadic_operands",
750 [InferTypeOpInterface, AttrSizedOperandSegments]> {
751 let arguments = (ins Variadic<I32>:$a, Variadic<I64>:$b);
752 let results = (outs Variadic<AnyType>:$outs);
753 let assemblyFormat = "`(` $a `:` type($a) `)` `(` $b `:` type($b) `)` attr-dict";
754 let extraClassDeclaration = [{
755 static ::llvm::LogicalResult inferReturnTypes(::mlir::MLIRContext *context,
756 ::std::optional<::mlir::Location> location, ::mlir::ValueRange operands,
757 ::mlir::DictionaryAttr attributes, mlir::OpaqueProperties properties, ::mlir::RegionRange regions,
758 ::llvm::SmallVectorImpl<::mlir::Type> &inferredReturnTypes) {
759 FormatInferTypeVariadicOperandsOpAdaptor adaptor(
760 operands, attributes, *properties.as<Properties *>(), {});
761 auto aTypes = adaptor.getA().getTypes();
762 auto bTypes = adaptor.getB().getTypes();
763 inferredReturnTypes.append(aTypes.begin(), aTypes.end());
764 inferredReturnTypes.append(bTypes.begin(), bTypes.end());
765 return ::mlir::success();
770 #endif // TEST_OPS_SYNTAX