//===-- TestOpsSyntax.td - Operations for testing syntax ---*- tablegen -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef TEST_OPS_SYNTAX #define TEST_OPS_SYNTAX include "TestAttrDefs.td" include "TestDialect.td" include "TestTypeDefs.td" include "mlir/Interfaces/InferTypeOpInterface.td" include "mlir/IR/OpBase.td" class TEST_Op traits = []> : Op; def WrappingRegionOp : TEST_Op<"wrapping_region", [SingleBlockImplicitTerminator<"TestReturnOp">]> { let summary = "wrapping region operation"; let description = [{ Test op wrapping another op in a region, to test calling parseGenericOperation from the custom parser. }]; let results = (outs Variadic); let regions = (region SizedRegion<1>:$region); let hasCustomAssemblyFormat = 1; } def PrettyPrintedRegionOp : TEST_Op<"pretty_printed_region", [SingleBlockImplicitTerminator<"TestReturnOp">]> { let summary = "pretty_printed_region operation"; let description = [{ Test-op can be printed either in a "pretty" or "non-pretty" way based on some criteria. The custom parser parsers both the versions while testing APIs: parseCustomOperationName & parseGenericOperationAfterOpName. }]; let arguments = (ins AnyType:$input1, AnyType:$input2 ); let results = (outs AnyType); let regions = (region SizedRegion<1>:$region); let hasCustomAssemblyFormat = 1; } def PolyForOp : TEST_Op<"polyfor", [OpAsmOpInterface]> { let summary = "polyfor operation"; let description = [{ Test op with multiple region arguments, each argument of index type. }]; let extraClassDeclaration = [{ void getAsmBlockArgumentNames(mlir::Region ®ion, mlir::OpAsmSetValueNameFn setNameFn); }]; let regions = (region SizedRegion<1>:$region); let hasCustomAssemblyFormat = 1; } def TestAttrWithLoc : TEST_Op<"attr_with_loc"> { let summary = "op's attribute has a location"; let arguments = (ins AnyAttr:$loc, AnyAttr:$value); let assemblyFormat = "`(` $value `` custom($loc) `)` attr-dict"; } // ----- // This is used to test that the fallback for a custom op's parser and printer // is the dialect parser and printer hooks. def CustomFormatFallbackOp : TEST_Op<"dialect_custom_format_fallback">; // Ops related to OIList primitive def OIListTrivial : TEST_Op<"oilist_with_keywords_only"> { let arguments = (ins UnitAttr:$keyword, UnitAttr:$otherKeyword, UnitAttr:$diffNameUnitAttrKeyword); let assemblyFormat = [{ oilist( `keyword` $keyword | `otherKeyword` $otherKeyword | `thirdKeyword` $diffNameUnitAttrKeyword) attr-dict }]; } def OIListSimple : TEST_Op<"oilist_with_simple_args", [AttrSizedOperandSegments]> { let arguments = (ins Optional:$arg0, Optional:$arg1, Optional:$arg2); let assemblyFormat = [{ oilist( `keyword` $arg0 `:` type($arg0) | `otherKeyword` $arg1 `:` type($arg1) | `thirdKeyword` $arg2 `:` type($arg2) ) attr-dict }]; } def OIListVariadic : TEST_Op<"oilist_variadic_with_parens", [AttrSizedOperandSegments]> { let arguments = (ins Variadic:$arg0, Variadic:$arg1, Variadic:$arg2); let assemblyFormat = [{ oilist( `keyword` `(` $arg0 `:` type($arg0) `)` | `otherKeyword` `(` $arg1 `:` type($arg1) `)` | `thirdKeyword` `(` $arg2 `:` type($arg2) `)`) attr-dict }]; } def OIListCustom : TEST_Op<"oilist_custom", [AttrSizedOperandSegments]> { let arguments = (ins Variadic:$arg0, Optional:$optOperand, UnitAttr:$nowait); let assemblyFormat = [{ oilist( `private` `(` $arg0 `:` type($arg0) `)` | `reduction` custom($optOperand) | `nowait` $nowait ) attr-dict }]; } def OIListAllowedLiteral : TEST_Op<"oilist_allowed_literal"> { let assemblyFormat = [{ oilist( `foo` | `bar` ) `buzz` attr-dict }]; } def TestEllipsisOp : TEST_Op<"ellipsis"> { let arguments = (ins Variadic:$operands, UnitAttr:$variadic); let assemblyFormat = [{ `(` $operands (`...` $variadic^)? `)` attr-dict `:` type($operands) `...` }]; } def ElseAnchorOp : TEST_Op<"else_anchor"> { let arguments = (ins Optional:$a); let assemblyFormat = "`(` (`?`) : (`` $a^ `:` type($a))? `)` attr-dict"; } // This is used to test that the default dialect is not elided when printing an // op with dots in the name to avoid parsing ambiguity. def OpWithDotInNameOp : TEST_Op<"op.with_dot_in_name"> { let assemblyFormat = "attr-dict"; } // -------------- //===----------------------------------------------------------------------===// // Test Op Asm Format //===----------------------------------------------------------------------===// def FormatLiteralOp : TEST_Op<"format_literal_op"> { let assemblyFormat = [{ `keyword_$.` `->` `:` `,` `=` `<` `>` `(` `)` `[` `]` `` `(` ` ` `)` `?` `+` `*` `{` `\n` `}` attr-dict }]; } // Test that we elide attributes that are within the syntax. def FormatAttrOp : TEST_Op<"format_attr_op"> { let arguments = (ins I64Attr:$attr); let assemblyFormat = "$attr attr-dict"; } // Test that we elide optional attributes that are within the syntax. def FormatOptAttrAOp : TEST_Op<"format_opt_attr_op_a"> { let arguments = (ins OptionalAttr:$opt_attr); let assemblyFormat = "(`(` $opt_attr^ `)` )? attr-dict"; } def FormatOptAttrBOp : TEST_Op<"format_opt_attr_op_b"> { let arguments = (ins OptionalAttr:$opt_attr); let assemblyFormat = "($opt_attr^)? attr-dict"; } // Test that we format symbol name attributes properly. def FormatSymbolNameAttrOp : TEST_Op<"format_symbol_name_attr_op"> { let arguments = (ins SymbolNameAttr:$attr); let assemblyFormat = "$attr attr-dict"; } // Test that we format optional symbol name attributes properly. def FormatOptSymbolNameAttrOp : TEST_Op<"format_opt_symbol_name_attr_op"> { let arguments = (ins OptionalAttr:$opt_attr); let assemblyFormat = "($opt_attr^)? attr-dict"; } // Test that we format optional symbol reference attributes properly. def FormatOptSymbolRefAttrOp : TEST_Op<"format_opt_symbol_ref_attr_op"> { let arguments = (ins OptionalAttr:$opt_attr); let assemblyFormat = "($opt_attr^)? attr-dict"; } // Test that we elide attributes that are within the syntax. def FormatAttrDictWithKeywordOp : TEST_Op<"format_attr_dict_w_keyword"> { let arguments = (ins I64Attr:$attr, OptionalAttr:$opt_attr); let assemblyFormat = "attr-dict-with-keyword"; } // Test that we don't need to provide types in the format if they are buildable. def FormatBuildableTypeOp : TEST_Op<"format_buildable_type_op"> { let arguments = (ins I64:$buildable); let results = (outs I64:$buildable_res); let assemblyFormat = "$buildable attr-dict"; } // Test various mixings of region formatting. class FormatRegionBase : TEST_Op<"format_region_" # suffix # "_op"> { let regions = (region AnyRegion:$region); let assemblyFormat = fmt; } def FormatRegionAOp : FormatRegionBase<"a", [{ regions attr-dict }]>; def FormatRegionBOp : FormatRegionBase<"b", [{ $region attr-dict }]>; def FormatRegionCOp : FormatRegionBase<"c", [{ (`region` $region^)? attr-dict }]>; class FormatVariadicRegionBase : TEST_Op<"format_variadic_region_" # suffix # "_op"> { let regions = (region VariadicRegion:$regions); let assemblyFormat = fmt; } def FormatVariadicRegionAOp : FormatVariadicRegionBase<"a", [{ $regions attr-dict }]>; def FormatVariadicRegionBOp : FormatVariadicRegionBase<"b", [{ ($regions^ `found_regions`)? attr-dict }]>; class FormatRegionImplicitTerminatorBase : TEST_Op<"format_implicit_terminator_region_" # suffix # "_op", [SingleBlockImplicitTerminator<"TestReturnOp">]> { let regions = (region AnyRegion:$region); let assemblyFormat = fmt; } def FormatFormatRegionImplicitTerminatorAOp : FormatRegionImplicitTerminatorBase<"a", [{ $region attr-dict }]>; // Test various mixings of result type formatting. class FormatResultBase : TEST_Op<"format_result_" # suffix # "_op"> { let results = (outs I64:$buildable_res, AnyMemRef:$result); let assemblyFormat = fmt; } def FormatResultAOp : FormatResultBase<"a", [{ type($result) attr-dict }]>; def FormatResultBOp : FormatResultBase<"b", [{ type(results) attr-dict }]>; def FormatResultCOp : FormatResultBase<"c", [{ functional-type($buildable_res, $result) attr-dict }]>; def FormatVariadicResult : TEST_Op<"format_variadic_result"> { let results = (outs Variadic:$result); let assemblyFormat = [{ `:` type($result) attr-dict}]; } def FormatMultipleVariadicResults : TEST_Op<"format_multiple_variadic_results", [AttrSizedResultSegments]> { let results = (outs Variadic:$result0, Variadic:$result1); let assemblyFormat = [{ `:` `(` type($result0) `)` `,` `(` type($result1) `)` attr-dict }]; } // Test various mixings of operand type formatting. class FormatOperandBase : TEST_Op<"format_operand_" # suffix # "_op"> { let arguments = (ins I64:$buildable, AnyMemRef:$operand); let assemblyFormat = fmt; } def FormatOperandAOp : FormatOperandBase<"a", [{ operands `:` type(operands) attr-dict }]>; def FormatOperandBOp : FormatOperandBase<"b", [{ operands `:` type($operand) attr-dict }]>; def FormatOperandCOp : FormatOperandBase<"c", [{ $buildable `,` $operand `:` type(operands) attr-dict }]>; def FormatOperandDOp : FormatOperandBase<"d", [{ $buildable `,` $operand `:` type($operand) attr-dict }]>; def FormatOperandEOp : FormatOperandBase<"e", [{ $buildable `,` $operand `:` type($buildable) `,` type($operand) attr-dict }]>; def FormatSuccessorAOp : TEST_Op<"format_successor_a_op", [Terminator]> { let successors = (successor VariadicSuccessor:$targets); let assemblyFormat = "$targets attr-dict"; } def FormatVariadicOperand : TEST_Op<"format_variadic_operand"> { let arguments = (ins Variadic:$operand); let assemblyFormat = [{ $operand `:` type($operand) attr-dict}]; } def FormatVariadicOfVariadicOperand : TEST_Op<"format_variadic_of_variadic_operand"> { let arguments = (ins VariadicOfVariadic:$operand, DenseI32ArrayAttr:$operand_segments ); let assemblyFormat = [{ $operand `:` type($operand) attr-dict}]; } def FormatMultipleVariadicOperands : TEST_Op<"format_multiple_variadic_operands", [AttrSizedOperandSegments]> { let arguments = (ins Variadic:$operand0, Variadic:$operand1); let assemblyFormat = [{ ` ` `(` $operand0 `)` `,` `(` $operand1 `:` type($operand1) `)` attr-dict }]; } // Test various mixings of optional operand and result type formatting. class FormatOptionalOperandResultOpBase : TEST_Op<"format_optional_operand_result_" # suffix # "_op", [AttrSizedOperandSegments]> { let arguments = (ins Optional:$optional, Variadic:$variadic); let results = (outs Optional:$optional_res); let assemblyFormat = fmt; } def FormatOptionalOperandResultAOp : FormatOptionalOperandResultOpBase<"a", [{ `(` $optional `:` type($optional) `)` `:` type($optional_res) (`[` $variadic^ `]`)? attr-dict }]>; def FormatOptionalOperandResultBOp : FormatOptionalOperandResultOpBase<"b", [{ (`(` $optional^ `:` type($optional) `)`)? `:` type($optional_res) (`[` $variadic^ `]`)? attr-dict }]>; // Test optional result type formatting. class FormatOptionalResultOpBase : TEST_Op<"format_optional_result_" # suffix # "_op", [AttrSizedResultSegments]> { let results = (outs Optional:$optional, Variadic:$variadic); let assemblyFormat = fmt; } def FormatOptionalResultAOp : FormatOptionalResultOpBase<"a", [{ (`:` type($optional)^ `->` type($variadic))? attr-dict }]>; def FormatOptionalResultBOp : FormatOptionalResultOpBase<"b", [{ (`:` type($optional) `->` type($variadic)^)? attr-dict }]>; def FormatOptionalResultCOp : FormatOptionalResultOpBase<"c", [{ (`:` functional-type($optional, $variadic)^)? attr-dict }]>; def FormatOptionalResultDOp : TEST_Op<"format_optional_result_d_op" > { let results = (outs Optional:$optional); let assemblyFormat = "(`:` type($optional)^)? attr-dict"; } def FormatTwoVariadicOperandsNoBuildableTypeOp : TEST_Op<"format_two_variadic_operands_no_buildable_type_op", [AttrSizedOperandSegments]> { let arguments = (ins Variadic:$a, Variadic:$b); let assemblyFormat = [{ `(` $a `:` type($a) `)` `->` `(` $b `:` type($b) `)` attr-dict }]; } def FormatInferVariadicTypeFromNonVariadic : TEST_Op<"format_infer_variadic_type_from_non_variadic", [SameOperandsAndResultType]> { let arguments = (ins Variadic:$args); let results = (outs AnyType:$result); let assemblyFormat = "operands attr-dict `:` type($result)"; } def FormatOptionalUnitAttr : TEST_Op<"format_optional_unit_attribute"> { let arguments = (ins UnitAttr:$is_optional); let assemblyFormat = "(`is_optional` $is_optional^)? attr-dict"; } def FormatOptionalUnitAttrNoElide : TEST_Op<"format_optional_unit_attribute_no_elide"> { let arguments = (ins UnitAttr:$is_optional); let assemblyFormat = "($is_optional^)? attr-dict"; } def FormatOptionalEnumAttr : TEST_Op<"format_optional_enum_attr"> { let arguments = (ins OptionalAttr:$attr); let assemblyFormat = "($attr^)? attr-dict"; } def FormatOptionalDefaultAttrs : TEST_Op<"format_optional_default_attrs"> { let arguments = (ins DefaultValuedStrAttr:$str, DefaultValuedStrAttr:$sym, DefaultValuedAttr:$e); let assemblyFormat = "($str^)? ($sym^)? ($e^)? attr-dict"; } def FormatOptionalWithElse : TEST_Op<"format_optional_else"> { let arguments = (ins UnitAttr:$isFirstBranchPresent); let assemblyFormat = "(`then` $isFirstBranchPresent^):(`else`)? attr-dict"; } def FormatCompoundAttr : TEST_Op<"format_compound_attr"> { let arguments = (ins CompoundAttrA:$compound); let assemblyFormat = "$compound attr-dict-with-keyword"; } def FormatNestedAttr : TEST_Op<"format_nested_attr"> { let arguments = (ins CompoundAttrNested:$nested); let assemblyFormat = "$nested attr-dict-with-keyword"; } def FormatNestedCompoundAttr : TEST_Op<"format_cpmd_nested_attr"> { let arguments = (ins CompoundNestedOuter:$nested); let assemblyFormat = "`nested` $nested attr-dict-with-keyword"; } def FormatMaybeEmptyType : TEST_Op<"format_maybe_empty_type"> { let arguments = (ins TestTypeOptionalValueType:$in); let assemblyFormat = "$in `:` type($in) attr-dict"; } def FormatQualifiedCompoundAttr : TEST_Op<"format_qual_cpmd_nested_attr"> { let arguments = (ins CompoundNestedOuter:$nested); let assemblyFormat = "`nested` qualified($nested) attr-dict-with-keyword"; } def FormatNestedType : TEST_Op<"format_cpmd_nested_type"> { let arguments = (ins CompoundNestedOuterType:$nested); let assemblyFormat = "$nested `nested` type($nested) attr-dict-with-keyword"; } def FormatQualifiedNestedType : TEST_Op<"format_qual_cpmd_nested_type"> { let arguments = (ins CompoundNestedOuterType:$nested); let assemblyFormat = "$nested `nested` qualified(type($nested)) attr-dict-with-keyword"; } //===----------------------------------------------------------------------===// // Custom Directives def FormatCustomDirectiveOperands : TEST_Op<"format_custom_directive_operands", [AttrSizedOperandSegments]> { let arguments = (ins I64:$operand, Optional:$optOperand, Variadic:$varOperands); let assemblyFormat = [{ custom( $operand, $optOperand, $varOperands ) attr-dict }]; } def FormatCustomDirectiveOperandsAndTypes : TEST_Op<"format_custom_directive_operands_and_types", [AttrSizedOperandSegments]> { let arguments = (ins AnyType:$operand, Optional:$optOperand, Variadic:$varOperands); let assemblyFormat = [{ custom( $operand, $optOperand, $varOperands, type($operand), type($optOperand), type($varOperands) ) attr-dict }]; } def FormatCustomDirectiveRegions : TEST_Op<"format_custom_directive_regions"> { let regions = (region AnyRegion:$region, VariadicRegion:$other_regions); let assemblyFormat = [{ custom( $region, $other_regions ) attr-dict }]; } def FormatCustomDirectiveResults : TEST_Op<"format_custom_directive_results", [AttrSizedResultSegments]> { let results = (outs AnyType:$result, Optional:$optResult, Variadic:$varResults); let assemblyFormat = [{ custom( type($result), type($optResult), type($varResults) ) attr-dict }]; } def FormatCustomDirectiveResultsWithTypeRefs : TEST_Op<"format_custom_directive_results_with_type_refs", [AttrSizedResultSegments]> { let results = (outs AnyType:$result, Optional:$optResult, Variadic:$varResults); let assemblyFormat = [{ custom( type($result), type($optResult), type($varResults) ) custom( ref(type($result)), ref(type($optResult)), ref(type($varResults)) ) attr-dict }]; } def FormatCustomDirectiveWithOptionalOperandRef : TEST_Op<"format_custom_directive_with_optional_operand_ref"> { let arguments = (ins Optional:$optOperand); let assemblyFormat = [{ ($optOperand^)? `:` custom(ref($optOperand)) attr-dict }]; } def FormatCustomDirectiveSuccessors : TEST_Op<"format_custom_directive_successors", [Terminator]> { let successors = (successor AnySuccessor:$successor, VariadicSuccessor:$successors); let assemblyFormat = [{ custom( $successor, $successors ) attr-dict }]; } def FormatCustomDirectiveAttributes : TEST_Op<"format_custom_directive_attributes"> { let arguments = (ins I64Attr:$attr, OptionalAttr:$optAttr); let assemblyFormat = [{ custom( $attr, $optAttr ) attr-dict }]; } def FormatCustomDirectiveSpacing : TEST_Op<"format_custom_directive_spacing"> { let arguments = (ins StrAttr:$attr1, StrAttr:$attr2); let assemblyFormat = [{ custom($attr1) custom($attr2) attr-dict }]; } def FormatCustomDirectiveAttrDict : TEST_Op<"format_custom_directive_attrdict"> { let arguments = (ins I64Attr:$attr, OptionalAttr:$optAttr); let assemblyFormat = [{ custom( attr-dict ) }]; } def FormatLiteralFollowingOptionalGroup : TEST_Op<"format_literal_following_optional_group"> { let arguments = (ins TypeAttr:$type, OptionalAttr:$value); let assemblyFormat = "(`(` $value^ `)`)? `:` $type attr-dict"; } //===----------------------------------------------------------------------===// // AllTypesMatch type inference def FormatAllTypesMatchVarOp : TEST_Op<"format_all_types_match_var", [ AllTypesMatch<["value1", "value2", "result"]> ]> { let arguments = (ins AnyType:$value1, AnyType:$value2); let results = (outs AnyType:$result); let assemblyFormat = "attr-dict $value1 `,` $value2 `:` type($value1)"; } def FormatAllTypesMatchAttrOp : TEST_Op<"format_all_types_match_attr", [ AllTypesMatch<["value1", "value2", "result"]> ]> { let arguments = (ins TypedAttrInterface:$value1, AnyType:$value2); let results = (outs AnyType:$result); let assemblyFormat = "attr-dict $value1 `,` $value2"; } //===----------------------------------------------------------------------===// // TypesMatchWith type inference def FormatTypesMatchVarOp : TEST_Op<"format_types_match_var", [ TypesMatchWith<"result type matches operand", "value", "result", "$_self"> ]> { let arguments = (ins AnyType:$value); let results = (outs AnyType:$result); let assemblyFormat = "attr-dict $value `:` type($value)"; } def FormatTypesMatchVariadicOp : TEST_Op<"format_types_match_variadic", [ RangedTypesMatchWith<"result type matches operand", "value", "result", "llvm::make_range($_self.begin(), $_self.end())"> ]> { let arguments = (ins Variadic:$value); let results = (outs Variadic:$result); let assemblyFormat = "attr-dict $value `:` type($value)"; } def FormatTypesMatchAttrOp : TEST_Op<"format_types_match_attr", [ TypesMatchWith<"result type matches constant", "value", "result", "$_self"> ]> { let arguments = (ins TypedAttrInterface:$value); let results = (outs AnyType:$result); let assemblyFormat = "attr-dict $value"; } def FormatTypesMatchContextOp : TEST_Op<"format_types_match_context", [ TypesMatchWith<"tuple result type matches operand type", "value", "result", "::mlir::TupleType::get($_ctxt, $_self)"> ]> { let arguments = (ins AnyType:$value); let results = (outs AnyType:$result); let assemblyFormat = "attr-dict $value `:` type($value)"; } //===----------------------------------------------------------------------===// // InferTypeOpInterface type inference in assembly format def FormatInferTypeOp : TEST_Op<"format_infer_type", [InferTypeOpInterface]> { let results = (outs AnyType); let assemblyFormat = "attr-dict"; let extraClassDeclaration = [{ static ::mlir::LogicalResult inferReturnTypes(::mlir::MLIRContext *context, ::std::optional<::mlir::Location> location, ::mlir::ValueRange operands, ::mlir::DictionaryAttr attributes, mlir::OpaqueProperties properties, ::mlir::RegionRange regions, ::llvm::SmallVectorImpl<::mlir::Type> &inferredReturnTypes) { inferredReturnTypes.assign({::mlir::IntegerType::get(context, 16)}); return ::mlir::success(); } }]; } // Check that formatget supports DeclareOpInterfaceMethods. def FormatInferType2Op : TEST_Op<"format_infer_type2", [DeclareOpInterfaceMethods]> { let results = (outs AnyType); let assemblyFormat = "attr-dict"; } // Base class for testing mixing allOperandTypes, allOperands, and // inferResultTypes. class FormatInferAllTypesBaseOp traits = []> : TEST_Op { let arguments = (ins Variadic:$args); let results = (outs Variadic:$outs); let extraClassDeclaration = [{ static ::mlir::LogicalResult inferReturnTypes(::mlir::MLIRContext *context, ::std::optional<::mlir::Location> location, ::mlir::ValueRange operands, ::mlir::DictionaryAttr attributes, mlir::OpaqueProperties properties, ::mlir::RegionRange regions, ::llvm::SmallVectorImpl<::mlir::Type> &inferredReturnTypes) { ::mlir::TypeRange operandTypes = operands.getTypes(); inferredReturnTypes.assign(operandTypes.begin(), operandTypes.end()); return ::mlir::success(); } }]; } // Test inferReturnTypes is called when allOperandTypes and allOperands is true. def FormatInferTypeAllOperandsAndTypesOp : FormatInferAllTypesBaseOp<"format_infer_type_all_operands_and_types"> { let assemblyFormat = "`(` operands `)` attr-dict `:` type(operands)"; } // Test inferReturnTypes is called when allOperandTypes is true and there is one // ODS operand. def FormatInferTypeAllOperandsAndTypesOneOperandOp : FormatInferAllTypesBaseOp<"format_infer_type_all_types_one_operand"> { let assemblyFormat = "`(` $args `)` attr-dict `:` type(operands)"; } // Test inferReturnTypes is called when allOperandTypes is true and there are // more than one ODS operands. def FormatInferTypeAllOperandsAndTypesTwoOperandsOp : FormatInferAllTypesBaseOp<"format_infer_type_all_types_two_operands", [SameVariadicOperandSize]> { let arguments = (ins Variadic:$args0, Variadic:$args1); let assemblyFormat = "`(` $args0 `)` `(` $args1 `)` attr-dict `:` type(operands)"; } // Test inferReturnTypes is called when allOperands is true and operand types // are separately specified. def FormatInferTypeAllTypesOp : FormatInferAllTypesBaseOp<"format_infer_type_all_types"> { let assemblyFormat = "`(` operands `)` attr-dict `:` type($args)"; } // Test inferReturnTypes coupled with regions. def FormatInferTypeRegionsOp : TEST_Op<"format_infer_type_regions", [InferTypeOpInterface]> { let results = (outs Variadic:$outs); let regions = (region AnyRegion:$region); let assemblyFormat = "$region attr-dict"; let extraClassDeclaration = [{ static ::mlir::LogicalResult inferReturnTypes(::mlir::MLIRContext *context, ::std::optional<::mlir::Location> location, ::mlir::ValueRange operands, ::mlir::DictionaryAttr attributes, mlir::OpaqueProperties properties, ::mlir::RegionRange regions, ::llvm::SmallVectorImpl<::mlir::Type> &inferredReturnTypes) { if (regions.empty()) return ::mlir::failure(); auto types = regions.front()->getArgumentTypes(); inferredReturnTypes.assign(types.begin(), types.end()); return ::mlir::success(); } }]; } // Test inferReturnTypes coupled with variadic operands (operandSegmentSizes). def FormatInferTypeVariadicOperandsOp : TEST_Op<"format_infer_type_variadic_operands", [InferTypeOpInterface, AttrSizedOperandSegments]> { let arguments = (ins Variadic:$a, Variadic:$b); let results = (outs Variadic:$outs); let assemblyFormat = "`(` $a `:` type($a) `)` `(` $b `:` type($b) `)` attr-dict"; let extraClassDeclaration = [{ static ::mlir::LogicalResult inferReturnTypes(::mlir::MLIRContext *context, ::std::optional<::mlir::Location> location, ::mlir::ValueRange operands, ::mlir::DictionaryAttr attributes, mlir::OpaqueProperties properties, ::mlir::RegionRange regions, ::llvm::SmallVectorImpl<::mlir::Type> &inferredReturnTypes) { FormatInferTypeVariadicOperandsOpAdaptor adaptor( operands, attributes, *properties.as(), {}); auto aTypes = adaptor.getA().getTypes(); auto bTypes = adaptor.getB().getTypes(); inferredReturnTypes.append(aTypes.begin(), aTypes.end()); inferredReturnTypes.append(bTypes.begin(), bTypes.end()); return ::mlir::success(); } }]; } #endif // TEST_OPS_SYNTAX