brintos

brintos / llvm-project-archived public Read only

0
0
Text · 136.5 KiB · 6702239 Raw
3919 lines · plain
1//===-- TestOps.td - Test dialect operation definitions ----*- tablegen -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef TEST_OPS10#define TEST_OPS11 12include "TestDialect.td"13include "TestInterfaces.td"14include "mlir/Dialect/DLTI/DLTIBase.td"15include "mlir/Dialect/Linalg/IR/LinalgInterfaces.td"16include "mlir/Dialect/LLVMIR/NVVMRequiresSMTraits.td"17include "mlir/IR/EnumAttr.td"18include "mlir/Interfaces/FunctionInterfaces.td"19include "mlir/IR/OpBase.td"20include "mlir/IR/OpAsmInterface.td"21include "mlir/IR/PatternBase.td"22include "mlir/IR/RegionKindInterface.td"23include "mlir/IR/SymbolInterfaces.td"24include "mlir/Interfaces/CallInterfaces.td"25include "mlir/Interfaces/ControlFlowInterfaces.td"26include "mlir/Interfaces/DataLayoutInterfaces.td"27include "mlir/Interfaces/DestinationStyleOpInterface.td"28include "mlir/Interfaces/InferIntRangeInterface.td"29include "mlir/Interfaces/InferTypeOpInterface.td"30include "mlir/Interfaces/LoopLikeInterface.td"31include "mlir/Interfaces/MemorySlotInterfaces.td"32include "mlir/Interfaces/SideEffectInterfaces.td"33include "mlir/Interfaces/TilingInterface.td"34include "mlir/Interfaces/ValueBoundsOpInterface.td"35include "mlir/Dialect/Bufferization/IR/BufferizableOpInterface.td"36include "mlir/Dialect/Bufferization/IR/BufferizationTypeInterfaces.td"37 38// Include the attribute definitions.39include "TestAttrDefs.td"40// Include the type definitions.41include "TestTypeDefs.td"42 43 44class TEST_Op<string mnemonic, list<Trait> traits = []> :45    Op<Test_Dialect, mnemonic, traits>;46 47//===----------------------------------------------------------------------===//48// Test Types49//===----------------------------------------------------------------------===//50 51def IntTypesOp : TEST_Op<"int_types"> {52  let results = (outs53    AnyI16:$any_i16,54    SI32:$si32,55    UI64:$ui64,56    AnyInteger:$any_int57  );58}59 60def ComplexF64 : Complex<F64>;61def ComplexOp : TEST_Op<"complex_f64"> {62  let results = (outs ComplexF64);63}64 65def ComplexTensorOp : TEST_Op<"complex_f64_tensor"> {66  let results = (outs TensorOf<[ComplexF64]>);67}68 69def TupleOp : TEST_Op<"tuple_32_bit"> {70  let results = (outs TupleOf<[I32, F32]>);71}72 73def NestedTupleOp : TEST_Op<"nested_tuple_32_bit"> {74  let results = (outs NestedTupleOf<[I32, F32]>);75}76 77def TakesStaticMemRefOp : TEST_Op<"takes_static_memref"> {78  let arguments = (ins AnyStaticShapeMemRef:$x);79}80 81def RankLessThan2I8F32MemRefOp : TEST_Op<"rank_less_than_2_I8_F32_memref"> {82  let results = (outs MemRefRankOf<[I8, F32], [0, 1]>);83}84 85def NDTensorOfOp : TEST_Op<"nd_tensor_of"> {86  let arguments = (ins87    0DTensorOf<[F32]>:$arg0,88    1DTensorOf<[F32]>:$arg1,89    2DTensorOf<[I16]>:$arg2,90    3DTensorOf<[I16]>:$arg3,91    4DTensorOf<[I16]>:$arg492  );93}94 95def RankedTensorOp : TEST_Op<"ranked_tensor_op"> {96  let arguments = (ins AnyRankedTensor:$input);97}98 99def MultiTensorRankOf : TEST_Op<"multi_tensor_rank_of"> {100  let arguments = (ins101    TensorRankOf<[I8, I32, F32], [0, 1]>:$arg0102  );103}104 105def TEST_TestType : DialectType<Test_Dialect,106    CPred<"::llvm::isa<::test::TestType>($_self)">, "test">,107    BuildableType<"$_builder.getType<::test::TestType>()">;108 109def SignlessLikeVariadic : TEST_Op<"signless_like_variadic"> {110  let arguments = (ins Variadic<SignlessIntegerLike>:$x);111}112 113//===----------------------------------------------------------------------===//114// Test Symbols115//===----------------------------------------------------------------------===//116 117def SymbolOp : TEST_Op<"symbol", [NoMemoryEffect, Symbol]> {118  let summary =  "operation which defines a new symbol";119  let arguments = (ins StrAttr:$sym_name,120                       OptionalAttr<StrAttr>:$sym_visibility);121}122 123def SymbolWithResultOp : TEST_Op<"symbol_with_result", [Symbol]> {124  let summary = "invalid symbol operation that produces an SSA result";125  let arguments = (ins StrAttr:$sym_name,126                       OptionalAttr<StrAttr>:$sym_visibility);127  let results = (outs AnyType:$result);128}129 130def OverriddenSymbolVisibilityOp : TEST_Op<"overridden_symbol_visibility", [131  DeclareOpInterfaceMethods<Symbol, ["getVisibility", "setVisibility"]>,132]> {133  let summary =  "operation overridden symbol visibility accessors";134  let arguments = (ins StrAttr:$sym_name);135}136 137def SymbolScopeOp : TEST_Op<"symbol_scope",138    [SymbolTable, SingleBlockImplicitTerminator<"TerminatorOp">]> {139  let summary =  "operation which defines a new symbol table";140  let regions = (region SizedRegion<1>:$region);141}142 143def SymbolScopeIsolatedOp144    : TEST_Op<"symbol_scope_isolated", [IsolatedFromAbove, SymbolTable,145                                        SingleBlockImplicitTerminator<146                                            "TerminatorOp">]> {147  let summary =148      "operation which defines a new symbol table that is IsolatedFromAbove";149  let regions = (region SizedRegion<1>:$region);150}151 152def SymbolTableRegionOp : TEST_Op<"symbol_table_region", [SymbolTable]> {153  let summary =  "operation which defines a new symbol table without a "154                 "restriction on a terminator";155  let regions = (region SizedRegion<1>:$region);156}157 158//===----------------------------------------------------------------------===//159// Test Operands160//===----------------------------------------------------------------------===//161 162def MixedNormalVariadicOperandOp : TEST_Op<163    "mixed_normal_variadic_operand", [SameVariadicOperandSize]> {164  let arguments = (ins165    Variadic<AnyTensor>:$input1,166    AnyTensor:$input2,167    Variadic<AnyTensor>:$input3168  );169}170def VariadicWithSameOperandsResult :171      TEST_Op<"variadic_with_same_operand_results",172              [SameOperandsAndResultType]> {173  let arguments = (ins Variadic<AnySignlessInteger>);174  let results = (outs AnySignlessInteger:$result);175}176 177def SameOperandsResultType : TEST_Op<178    "same_operand_result_type", [SameOperandsAndResultType]> {179  let arguments = (ins AnyTensor:$operand);180  let results = (outs AnyTensor:$result);181}182 183//===----------------------------------------------------------------------===//184// Test Results185//===----------------------------------------------------------------------===//186 187def MixedNormalVariadicResults : TEST_Op<188    "mixed_normal_variadic_result", [SameVariadicResultSize]> {189  let results = (outs190    Variadic<AnyTensor>:$output1,191    AnyTensor:$output2,192    Variadic<AnyTensor>:$output3193  );194}195 196//===----------------------------------------------------------------------===//197// Test Attributes198//===----------------------------------------------------------------------===//199 200def AnyAttrOfOp : TEST_Op<"any_attr_of_i32_str"> {201  let arguments = (ins AnyAttrOf<[I32Attr, StrAttr]>:$attr);202}203 204def NonNegIntAttrOp : TEST_Op<"non_negative_int_attr"> {205  let arguments = (ins206      ConfinedAttr<I32Attr, [IntNonNegative]>:$i32attr,207      ConfinedAttr<I64Attr, [IntNonNegative]>:$i64attr208  );209}210 211def PositiveIntAttrOp : TEST_Op<"positive_int_attr"> {212  let arguments = (ins213      ConfinedAttr<I32Attr, [IntPositive]>:$i32attr,214      ConfinedAttr<I64Attr, [IntPositive]>:$i64attr215  );216}217 218def TypeArrayAttrOp : TEST_Op<"type_array_attr"> {219  let arguments = (ins TypeArrayAttr:$attr);220}221 222def TypeArrayAttrWithDefaultOp : TEST_Op<"type_array_attr_with_default"> {223  let arguments = (ins DefaultValuedAttr<TypeArrayAttr, "{}">:$attr);224}225 226def TypedStringAttrWithTypeOp : TEST_Op<"string_attr_with_type"> {227  let arguments = (ins TypedStrAttr<AnyInteger>:$attr);228  let assemblyFormat = "$attr attr-dict";229}230 231def TypedStringAttrWithMixedTypeOp : TEST_Op<"string_attr_with_mixed_type"> {232  let arguments = (ins233    AnyAttrOf<[TypedStrAttr<AnyInteger>, I64Attr]>:$attr234  );235  let assemblyFormat = "$attr attr-dict";236}237 238def FloatAttrOp : TEST_Op<"float_attrs"> {239  // TODO: Clean up the OpBase float type and attribute selectors so they240  // can express all of the types.241  let arguments = (ins242    AnyAttr:$float_attr243  );244}245 246def I32EnumAttrOp : TEST_Op<"i32_enum_attr"> {247  let arguments = (ins SomeI32Enum:$attr);248  let results = (outs I32:$val);249}250 251def I64EnumAttrOp : TEST_Op<"i64_enum_attr"> {252  let arguments = (ins SomeI64Enum:$attr);253  let results = (outs I32:$val);254}255 256def IntAttrOp : TEST_Op<"int_attrs"> {257  let arguments = (ins258    AnyI32Attr:$any_i32_attr,259    IndexAttr:$index_attr,260    UI32Attr:$ui32_attr,261    SI32Attr:$si32_attr262  );263}264 265def FloatElementsAttrOp : TEST_Op<"float_elements_attr"> {266  let arguments = (ins267      RankedF32ElementsAttr<[2]>:$scalar_f32_attr,268      RankedF64ElementsAttr<[4, 8]>:$tensor_f64_attr269  );270}271 272// A pattern that updates dense<[3.0, 4.0]> to dense<[5.0, 6.0]>.273// This tests both matching and generating float elements attributes.274def UpdateFloatElementsAttr : Pat<275  (FloatElementsAttrOp276    ConstantAttr<RankedF32ElementsAttr<[2]>, "{3.0f, 4.0f}">:$f32attr,277    $f64attr),278  (FloatElementsAttrOp279    ConstantAttr<RankedF32ElementsAttr<[2]>, "{5.0f, 6.0f}">:$f32attr,280    $f64attr)>;281 282def IntElementsAttrOp : TEST_Op<"int_elements_attr"> {283  let arguments = (ins284      AnyI32ElementsAttr:$any_i32_attr,285      I32ElementsAttr:$i32_attr286  );287}288 289def RankedIntElementsAttrOp : TEST_Op<"ranked_int_elements_attr"> {290  let arguments = (ins291      RankedI32ElementsAttr<[2]>:$vector_i32_attr,292      RankedI64ElementsAttr<[4, 8]>:$matrix_i64_attr293  );294}295 296def DerivedTypeAttrOp : TEST_Op<"derived_type_attr", []> {297  let results = (outs AnyTensor:$output);298  DerivedTypeAttr element_dtype =299    DerivedTypeAttr<"return getElementTypeOrSelf(getOutput().getType());">;300  DerivedAttr num_elements = DerivedAttr<"int",301    "return ::llvm::cast<ShapedType>(getOutput().getType()).getNumElements();",302    "$_builder.getI32IntegerAttr($_self)">;303}304 305def TestPropOp : TEST_Op<"prop">,306  Arguments<(ins Variadic<Index>:$upperInits,307      I32ElementsAttr:$transforms)>,308  Results<(outs Variadic<AnyType>:$results)> {309  DerivedAttr upperLen = DerivedAttr<"uint32_t", [{310    return getUpperInits().size() / getTransforms().size();311  }], [{ $_builder.getI32IntegerAttr($_self) }]>;312}313 314 315def StringElementsAttrOp : TEST_Op<"string_elements_attr"> {316  let arguments = (ins317      StringElementsAttr:$scalar_string_attr318  );319}320 321def TypedAttrOp : TEST_Op<"typed_attr"> {322  let arguments = (ins TypeAttr:$type, AnyAttr:$attr);323  let assemblyFormat = [{324    attr-dict $type `=` custom<AttrElideType>(ref($type), $attr)325  }];326}327 328def TypeAttrOfOp : TEST_Op<"type_attr_of"> {329  let arguments = (ins TypeAttrOf<I64>:$type);330  let assemblyFormat = [{331    attr-dict $type332  }];333}334 335def DenseArrayAttrOp : TEST_Op<"dense_array_attr"> {336  let arguments = (ins337    DenseBoolArrayAttr:$i1attr,338    DenseI8ArrayAttr:$i8attr,339    DenseI16ArrayAttr:$i16attr,340    DenseI32ArrayAttr:$i32attr,341    DenseI64ArrayAttr:$i64attr,342    DenseF32ArrayAttr:$f32attr,343    DenseF64ArrayAttr:$f64attr,344    DenseI32ArrayAttr:$emptyattr345  );346  let assemblyFormat = [{347   `i1attr` `=` $i1attr `i8attr` `=` $i8attr `i16attr` `=` $i16attr348   `i32attr` `=` $i32attr `i64attr` `=` $i64attr  `f32attr` `=` $f32attr349   `f64attr` `=` $f64attr `emptyattr` `=` $emptyattr attr-dict350  }];351}352 353def SlashAttrOp : TEST_Op<"slash_attr"> {354  let arguments = (ins SlashAttr:$attr);355}356 357//===----------------------------------------------------------------------===//358// Test Attributes Constraints359//===----------------------------------------------------------------------===//360 361def ConfinedDenseArrayAttrOp : TEST_Op<"confined_dense_array_attr"> {362  let arguments = (ins363      ConfinedAttr<DenseI16ArrayAttr,364                   [DenseArrayStrictlySorted<DenseI16ArrayAttr>]>:$emptyattr,365      ConfinedAttr<DenseI32ArrayAttr,366                   [DenseArraySorted<DenseI32ArrayAttr>]>:$i32attr,367      ConfinedAttr<DenseI64ArrayAttr,368                   [DenseArrayStrictlySorted<DenseI64ArrayAttr>]>:$i64attr369  );370}371 372// It does not make sense to have this constraint on a DenseBoolArrayAttr.373def DenseArrayStrictlyPositiveAttrOp : TEST_Op<"confined_strictly_positive_attr"> {374  let arguments = (ins375      ConfinedAttr<DenseI8ArrayAttr,376                   [DenseArrayStrictlyPositive<DenseI8ArrayAttr>]>:$i8attr,377      ConfinedAttr<DenseI16ArrayAttr,378                   [DenseArrayStrictlyPositive<DenseI16ArrayAttr>]>:$i16attr,379      ConfinedAttr<DenseI32ArrayAttr,380                   [DenseArrayStrictlyPositive<DenseI32ArrayAttr>]>:$i32attr,381      ConfinedAttr<DenseI64ArrayAttr,382                   [DenseArrayStrictlyPositive<DenseI64ArrayAttr>]>:$i64attr,383      ConfinedAttr<DenseF32ArrayAttr,384                   [DenseArrayStrictlyPositive<DenseF32ArrayAttr>]>:$f32attr,385      ConfinedAttr<DenseF64ArrayAttr,386                   [DenseArrayStrictlyPositive<DenseF64ArrayAttr>]>:$f64attr,387      ConfinedAttr<DenseI16ArrayAttr,388                   [DenseArrayStrictlyPositive<DenseI16ArrayAttr>]>:$emptyattr389  );390}391 392// It does not make sense to have this constraint on a DenseBoolArrayAttr.393// It is always true.394def DenseArrayNonNegativeOp : TEST_Op<"confined_non_negative_attr"> {395  let arguments = (ins396      ConfinedAttr<DenseI8ArrayAttr,397                   [DenseArrayNonNegative<DenseI8ArrayAttr>]>:$i8attr,398      ConfinedAttr<DenseI16ArrayAttr,399                   [DenseArrayNonNegative<DenseI16ArrayAttr>]>:$i16attr,400      ConfinedAttr<DenseI32ArrayAttr,401                   [DenseArrayNonNegative<DenseI32ArrayAttr>]>:$i32attr,402      ConfinedAttr<DenseI64ArrayAttr,403                   [DenseArrayNonNegative<DenseI64ArrayAttr>]>:$i64attr,404      ConfinedAttr<DenseF32ArrayAttr,405                   [DenseArrayNonNegative<DenseF32ArrayAttr>]>:$f32attr,406      ConfinedAttr<DenseF64ArrayAttr,407                   [DenseArrayNonNegative<DenseF64ArrayAttr>]>:$f64attr,408      ConfinedAttr<DenseI16ArrayAttr,409                   [DenseArrayNonNegative<DenseI16ArrayAttr>]>:$emptyattr410  );411}412 413//===----------------------------------------------------------------------===//414// Test Promised Interfaces Constraints415//===----------------------------------------------------------------------===//416 417def PromisedInterfacesOp : TEST_Op<"promised_interfaces"> {418  let arguments = (ins419      ConfinedAttr<AnyAttr,420          [PromisedAttrInterface<TestExternalAttrInterface>]>:$promisedAttr,421      ConfinedType<AnyType,422          [HasPromiseOrImplementsTypeInterface<TestExternalTypeInterface>]423        >:$promisedType424  );425}426 427//===----------------------------------------------------------------------===//428// Test Enum Attributes429//===----------------------------------------------------------------------===//430 431// Define the enum attribute.432def TestEnumAttr : EnumAttr<Test_Dialect, TestEnum, "enum">;433 434// Define an op that contains the enum attribute.435def OpWithEnum : TEST_Op<"op_with_enum"> {436  let arguments = (ins TestEnumAttr:$value, OptionalAttr<AnyAttr>:$tag);437  let assemblyFormat = "$value (`tag` $tag^)? attr-dict";438}439 440// Define a pattern that matches and creates an enum attribute.441def : Pat<(OpWithEnum ConstantEnumCase<TestEnumAttr, "first">:$value,442                      ConstantAttr<I32Attr, "0">:$tag),443          (OpWithEnum ConstantEnumCase<TestEnumAttr, "second">,444                      ConstantAttr<I32Attr, "1">)>;445 446//===----------------------------------------------------------------------===//447// Test Enum Properties448//===----------------------------------------------------------------------===//449 450// Define the enum property.451def TestEnumProp : EnumProp<TestEnum>;452// Define an op that contains the enum property.453def OpWithEnumProp : TEST_Op<"op_with_enum_prop"> {454  let arguments = (ins TestEnumProp:$value);455  let assemblyFormat = "$value attr-dict";456}457 458def TestEnumPropAttrForm : EnumPropWithAttrForm<TestEnum, TestEnumAttr>;459def OpWithEnumPropAttrForm : TEST_Op<"op_with_enum_prop_attr_form"> {460  let arguments = (ins TestEnumPropAttrForm:$value);461  let assemblyFormat = "prop-dict attr-dict";462}463 464def TestEnumPropAttrFormAlways : EnumPropWithAttrForm<TestEnum, TestEnumAttr> {465  let storeInCustomAttribute = 1;466}467def OpWithEnumPropAttrFormAlways : TEST_Op<"op_with_enum_prop_attr_form_always"> {468  let arguments = (ins TestEnumPropAttrFormAlways:$value);469  let assemblyFormat = "prop-dict attr-dict";470}471 472def TestBitEnumProp : EnumProp<TestBitEnum> {473  let defaultValue = TestBitEnum.cppType # "::Read";474}475def OpWithTestBitEnum : TEST_Op<"op_with_bit_enum_prop"> {476  let arguments = (ins477    TestBitEnumProp:$value1,478    TestBitEnumProp:$value2);479  let assemblyFormat = "$value1 ($value2^)? attr-dict `:` `(``)`";480}481 482def TestBitEnumPropNamed : NamedEnumProp<TestBitEnum, "bit_enum"> {483  let defaultValue = TestBitEnum.cppType # "::Read";484}485def OpWithBitEnumPropNamed : TEST_Op<"op_with_bit_enum_prop_named"> {486  let arguments = (ins487    TestBitEnumPropNamed:$value1,488    TestBitEnumPropNamed:$value2);489  let assemblyFormat = "$value1 ($value2^)? attr-dict";490}491 492//===----------------------------------------------------------------------===//493// Test Bit Enum Attributes494//===----------------------------------------------------------------------===//495 496// Define the enum attribute.497def TestBitEnumAttr : EnumAttr<Test_Dialect, TestBitEnum, "bit_enum"> {498  let assemblyFormat = "`<` $value `>`";499}500 501// Define an op that contains the enum attribute.502def OpWithBitEnum : TEST_Op<"op_with_bit_enum"> {503  let arguments = (ins TestBitEnumAttr:$value, OptionalAttr<AnyAttr>:$tag);504  let assemblyFormat = "$value (`tag` $tag^)? attr-dict";505}506 507def TestBitEnumVerticalBarAttr508    : EnumAttr<Test_Dialect, TestBitEnumVerticalBar, "bit_enum_vbar"> {509  let assemblyFormat = "`<` $value `>`";510}511 512// Define an op that contains the enum attribute.513def OpWithBitEnumVerticalBar : TEST_Op<"op_with_bit_enum_vbar"> {514  let arguments = (ins TestBitEnumVerticalBarAttr:$value,515                   OptionalAttr<AnyAttr>:$tag);516  let assemblyFormat = "$value (`tag` $tag^)? attr-dict";517}518 519// Define a pattern that matches and creates a bit enum attribute.520def : Pat<(OpWithBitEnum ConstantEnumCase<TestBitEnumAttr, "write|execute">,521                         ConstantAttr<I32Attr, "0">),522          (OpWithBitEnum ConstantEnumCase<TestBitEnumAttr, "execute|read">,523                         ConstantAttr<I32Attr, "1">)>;524 525//===----------------------------------------------------------------------===//526// Test Regions527//===----------------------------------------------------------------------===//528 529def OneRegionOp : TEST_Op<"one_region_op", []> {530  let regions = (region AnyRegion);531}532 533def TwoRegionOp : TEST_Op<"two_region_op", []> {534  let regions = (region AnyRegion, AnyRegion);535}536 537def SizedRegionOp : TEST_Op<"sized_region_op", []> {538  let regions = (region SizedRegion<2>:$my_region, SizedRegion<1>);539}540 541def VariadicRegionInferredTypesOp : TEST_Op<"variadic_region_inferred",542                                            [InferTypeOpInterface]> {543  let regions = (region VariadicRegion<AnyRegion>:$bodies);544  let results = (outs Variadic<AnyType>);545 546  let extraClassDeclaration = [{547    static llvm::LogicalResult inferReturnTypes(mlir::MLIRContext *context,548          std::optional<::mlir::Location> location, mlir::ValueRange operands,549          mlir::DictionaryAttr attributes, mlir::OpaqueProperties properties, mlir::RegionRange regions,550          llvm::SmallVectorImpl<mlir::Type> &inferredReturnTypes) {551      inferredReturnTypes.assign({mlir::IntegerType::get(context, 16)});552      return mlir::success();553    }554  }];555}556 557def OneRegionWithOperandsOp : TEST_Op<"one_region_with_operands_op", []> {558  let arguments = (ins Variadic<AnyType>:$operands);559  let regions = (region AnyRegion);560}561 562def IsolatedOneRegionOp : TEST_Op<"isolated_one_region_op", [IsolatedFromAbove]> {563  let arguments = (ins Variadic<AnyType>:$operands);564  let results = (outs Variadic<AnyType>:$results);565  let regions = (region AnyRegion:$my_region);566  let assemblyFormat = [{567    attr-dict-with-keyword $operands $my_region `:` type($operands) `->` type($results)568  }];569}570 571def IsolatedRegionsOp : TEST_Op<"isolated_regions", [IsolatedFromAbove]> {572  let regions = (region VariadicRegion<AnyRegion>:$regions);573  let assemblyFormat = "attr-dict-with-keyword $regions";574}575 576def AllocaScopeRegionOp : TEST_Op<"alloca_scope_region",577                                  [AutomaticAllocationScope]> {578  let regions = (region AnyRegion:$region);579  let assemblyFormat = "attr-dict-with-keyword $region";580}581 582def OneRegionWithRecursiveMemoryEffectsOp583    : TEST_Op<"one_region_with_recursive_memory_effects", [584        RecursiveMemoryEffects]> {585  let description = [{586    Op that has one region and recursive side effects. The587    RegionBranchOpInterface is not implemented on this op.588  }];589  let results = (outs AnyType:$result);590  let regions = (region SizedRegion<1>:$body);591}592 593//===----------------------------------------------------------------------===//594// NoTerminator Operation595//===----------------------------------------------------------------------===//596 597def SingleNoTerminatorOp : TEST_Op<"single_no_terminator_op",598                                   GraphRegionNoTerminator.traits> {599  let regions = (region SizedRegion<1>:$my_region);600 601  let assemblyFormat = "attr-dict `:` $my_region";602}603 604def SingleNoTerminatorCustomAsmOp : TEST_Op<"single_no_terminator_custom_asm_op",605                                            [SingleBlock, NoTerminator]> {606  let regions = (region SizedRegion<1>);607  let hasCustomAssemblyFormat = 1;608}609 610def VariadicNoTerminatorOp : TEST_Op<"variadic_no_terminator_op",611                                     GraphRegionNoTerminator.traits> {612  let regions = (region VariadicRegion<SizedRegion<1>>:$my_regions);613 614  let assemblyFormat = "attr-dict `:` $my_regions";615}616 617//===----------------------------------------------------------------------===//618// Test Call Interfaces619//===----------------------------------------------------------------------===//620 621def TestCallOp : TEST_Op<"call", [DeclareOpInterfaceMethods<SymbolUserOpInterface>]> {622  let arguments = (ins FlatSymbolRefAttr:$callee, Variadic<AnyType>:$operands);623  let results = (outs Variadic<AnyType>);624  let assemblyFormat = [{625    $callee `(` $operands `)` attr-dict `:` functional-type($operands, results)626  }];627}628 629def ConversionCallOp : TEST_Op<"conversion_call_op",630    [CallOpInterface]> {631  let arguments = (ins632    Variadic<AnyType>:$arg_operands,633    SymbolRefAttr:$callee,634    OptionalAttr<DictArrayAttr>:$arg_attrs,635    OptionalAttr<DictArrayAttr>:$res_attrs636  );637  let results = (outs Variadic<AnyType>);638 639  let extraClassDeclaration = [{640    /// Return the callee of this operation.641    ::mlir::CallInterfaceCallable getCallableForCallee();642 643    /// Set the callee for this operation.644    void setCalleeFromCallable(::mlir::CallInterfaceCallable);645  }];646  let extraClassDefinition = [{647    ::mlir::CallInterfaceCallable $cppClass::getCallableForCallee() {648      return (*this)->getAttrOfType<::mlir::SymbolRefAttr>("callee");649    }650 651    void $cppClass::setCalleeFromCallable(::mlir::CallInterfaceCallable callee) {652      (*this)->setAttr("callee", cast<SymbolRefAttr>(callee));653    }654  }];655}656 657def ConversionFuncOp : TEST_Op<"conversion_func_op", [FunctionOpInterface]> {658  let arguments = (ins SymbolNameAttr:$sym_name,659                       TypeAttrOf<FunctionType>:$function_type,660                       OptionalAttr<DictArrayAttr>:$arg_attrs,661                       OptionalAttr<DictArrayAttr>:$res_attrs,662                       OptionalAttr<StrAttr>:$sym_visibility);663  let regions = (region AnyRegion:$body);664 665  let extraClassDeclaration = [{666    //===------------------------------------------------------------------===//667    // FunctionOpInterface Methods668    //===------------------------------------------------------------------===//669 670    /// Returns the region on the current operation that is callable. This may671    /// return null in the case of an external callable object, e.g. an external672    /// function.673    ::mlir::Region *getCallableRegion() {674      return isExternal() ? nullptr : &getBody();675    }676 677    /// Returns the argument types of this async function.678    ::mlir::ArrayRef<::mlir::Type> getArgumentTypes() {679      return getFunctionType().getInputs();680    }681 682    /// Returns the result types of this async function.683    ::mlir::ArrayRef<::mlir::Type> getResultTypes() {684      return getFunctionType().getResults();685    }686 687    /// Returns the number of results of this async function688    unsigned getNumResults() {return getResultTypes().size();}689  }];690 691  let hasCustomAssemblyFormat = 1;692}693 694def FunctionalRegionOp : TEST_Op<"functional_region_op",695    [CallableOpInterface]> {696  let regions = (region AnyRegion:$body);697  let arguments = (ins698    OptionalAttr<DictArrayAttr>:$arg_attrs,699    OptionalAttr<DictArrayAttr>:$res_attrs700  );701  let results = (outs FunctionType);702 703  let extraClassDeclaration = [{704    ::mlir::Region *getCallableRegion() { return &getBody(); }705    ::llvm::ArrayRef<::mlir::Type> getResultTypes() {706      return ::llvm::cast<::mlir::FunctionType>(getType()).getResults();707    }708    ::llvm::ArrayRef<::mlir::Type> getArgumentTypes() {709      return ::llvm::cast<::mlir::FunctionType>(getType()).getInputs();710    }711  }];712}713 714 715def FoldToCallOp : TEST_Op<"fold_to_call_op"> {716  let arguments = (ins FlatSymbolRefAttr:$callee);717  let hasCanonicalizer = 1;718}719 720//===----------------------------------------------------------------------===//721// Test Traits722//===----------------------------------------------------------------------===//723 724def SameOperandElementTypeOp : TEST_Op<"same_operand_element_type",725    [SameOperandsElementType]> {726  let arguments = (ins AnyType, AnyType);727  let results = (outs AnyType);728}729 730def SameOperandAndResultElementTypeOp :731    TEST_Op<"same_operand_and_result_element_type",732    [SameOperandsAndResultElementType]> {733  let arguments = (ins Variadic<AnyType>);734  let results = (outs Variadic<AnyType>);735}736 737def SameOperandShapeOp : TEST_Op<"same_operand_shape", [SameOperandsShape]> {738  let arguments = (ins Variadic<AnyShaped>);739}740 741def SameOperandAndResultShapeOp : TEST_Op<"same_operand_and_result_shape",742    [SameOperandsAndResultShape]> {743  let arguments = (ins Variadic<AnyShaped>);744  let results = (outs Variadic<AnyShaped>);745}746 747def SameOperandAndResultTypeOp : TEST_Op<"same_operand_and_result_type",748    [SameOperandsAndResultType]> {749  let arguments = (ins Variadic<AnyType>);750  let results = (outs Variadic<AnyType>);751}752 753def ElementwiseMappableOp : TEST_Op<"elementwise_mappable",754    ElementwiseMappable.traits> {755  let arguments = (ins Variadic<AnyType>);756  let results = (outs Variadic<AnyType>);757}758 759def ArgAndResHaveFixedElementTypesOp :760    TEST_Op<"arg_and_res_have_fixed_element_types",761      [PredOpTrait<"fixed type combination",762         And<[ElementTypeIsPred<"x", I32>,763              ElementTypeIsPred<"y", F32>]>>,764      ElementTypeIs<"res", I16>]> {765  let arguments = (ins766    AnyShaped:$x, AnyShaped:$y);767  let results = (outs AnyShaped:$res);768}769 770def OperandsHaveSameElementType : TEST_Op<"operands_have_same_element_type", [771    AllElementTypesMatch<["x", "y"]>]> {772  let arguments = (ins AnyType:$x, AnyType:$y);773}774 775def OperandZeroAndResultHaveSameElementType : TEST_Op<776    "operand0_and_result_have_same_element_type",777    [AllElementTypesMatch<["x", "res"]>]> {778  let arguments = (ins AnyType:$x, AnyType:$y);779  let results = (outs AnyType:$res);780}781 782def OperandsHaveSameType :783    TEST_Op<"operands_have_same_type", [AllTypesMatch<["x", "y"]>]> {784  let arguments = (ins AnyType:$x, AnyType:$y);785}786 787def ResultHasSameTypeAsAttr :788    TEST_Op<"result_has_same_type_as_attr",789            [AllTypesMatch<["attr", "result"]>]> {790  let arguments = (ins TypedAttrInterface:$attr);791  let results = (outs AnyType:$result);792  let assemblyFormat = "$attr `->` type($result) attr-dict";793}794 795def OperandZeroAndResultHaveSameType :796    TEST_Op<"operand0_and_result_have_same_type",797            [AllTypesMatch<["x", "res"]>]> {798  let arguments = (ins AnyType:$x, AnyType:$y);799  let results = (outs AnyType:$res);800}801 802def OperandsHaveSameRank :803    TEST_Op<"operands_have_same_rank", [AllRanksMatch<["x", "y"]>]> {804  let arguments = (ins AnyShaped:$x, AnyShaped:$y);805}806 807def OperandZeroAndResultHaveSameRank :808    TEST_Op<"operand0_and_result_have_same_rank",809            [AllRanksMatch<["x", "res"]>]> {810  let arguments = (ins AnyShaped:$x, AnyShaped:$y);811  let results = (outs AnyShaped:$res);812}813 814def OperandsAndResultHaveSameRank :815    TEST_Op<"operands_and_result_have_same_rank", [SameOperandsAndResultRank]> {816  let arguments = (ins AnyShaped:$x, AnyShaped:$y);817  let results = (outs AnyShaped:$res);818}819 820def OperandZeroAndResultHaveSameShape :821    TEST_Op<"operand0_and_result_have_same_shape",822            [AllShapesMatch<["x", "res"]>]> {823  let arguments = (ins AnyShaped:$x, AnyShaped:$y);824  let results = (outs AnyShaped:$res);825}826 827def OperandZeroAndResultHaveSameElementCount :828    TEST_Op<"operand0_and_result_have_same_element_count",829            [AllElementCountsMatch<["x", "res"]>]> {830  let arguments = (ins AnyShaped:$x, AnyShaped:$y);831  let results = (outs AnyShaped:$res);832}833 834def FourEqualsFive :835    TEST_Op<"four_equals_five", [AllMatch<["5", "4"], "4 equals 5">]>;836 837def OperandRankEqualsResultSize :838    TEST_Op<"operand_rank_equals_result_size",839            [AllMatch<[Rank<"operand">.result, ElementCount<"result">.result],840                      "operand rank equals result size">]> {841  let arguments = (ins AnyShaped:$operand);842  let results = (outs AnyShaped:$result);843}844 845def IfFirstOperandIsNoneThenSoIsSecond :846    TEST_Op<"if_first_operand_is_none_then_so_is_second", [PredOpTrait<847    "has either both none type operands or first is not none",848     Or<[849        And<[TypeIsPred<"x", NoneType>, TypeIsPred<"y", NoneType>]>,850        Neg<TypeIsPred<"x", NoneType>>]>>]> {851  let arguments = (ins AnyType:$x, AnyType:$y);852}853 854def BroadcastableOp : TEST_Op<"broadcastable", [ResultsBroadcastableShape]> {855  let arguments = (ins Variadic<AnyTensor>);856  let results = (outs AnyTensor);857}858 859// HasParent trait860def ParentOp : TEST_Op<"parent"> {861    let regions = (region AnyRegion);862}863def ChildOp : TEST_Op<"child", [HasParent<"ParentOp">]>;864 865// ParentOneOf trait866def ParentOp1 : TEST_Op<"parent1"> {867  let regions = (region AnyRegion);868}869def ChildWithParentOneOf : TEST_Op<"child_with_parent_one_of",870                                [ParentOneOf<["ParentOp", "ParentOp1"]>]>;871 872def TerminatorOp : TEST_Op<"finish", [Terminator]>;873def SingleBlockImplicitTerminatorOp : TEST_Op<"SingleBlockImplicitTerminator",874    [SingleBlockImplicitTerminator<"TerminatorOp">]> {875  let regions = (region SizedRegion<1>:$region);876}877 878def I32ElementsAttrOp : TEST_Op<"i32ElementsAttr"> {879  let arguments = (ins I32ElementsAttr:$attr);880}881 882def IndexElementsAttrOp : TEST_Op<"indexElementsAttr"> {883  let arguments = (ins IndexElementsAttr:$attr);884}885 886def OpWithInferTypeInterfaceOp : TEST_Op<"op_with_infer_type_if", [887    DeclareOpInterfaceMethods<InferTypeOpInterface>]> {888  let arguments = (ins AnyTensor, AnyTensor);889  let results = (outs AnyTensor);890}891 892def OpWithInferTypeAdaptorInterfaceOp : TEST_Op<"op_with_infer_type_adaptor_if", [893    InferTypeOpAdaptor]> {894  let arguments = (ins AnyTensor:$x, AnyTensor:$y);895  let results = (outs AnyTensor);896}897 898def OpWithRefineTypeInterfaceOp : TEST_Op<"op_with_refine_type_if", [899    DeclareOpInterfaceMethods<InferTypeOpInterface,900        ["refineReturnTypes"]>]> {901  let arguments = (ins AnyTensor, AnyTensor);902  let results = (outs AnyTensor);903}904 905def OpWithShapedTypeInferTypeInterfaceOp : TEST_Op<"op_with_shaped_type_infer_type_if",906      [InferTensorTypeWithReify]> {907  let arguments = (ins AnyTensor, AnyTensor);908  let results = (outs AnyTensor);909}910 911def OpWithShapedTypeInferTypeAdaptorInterfaceOp :912      TEST_Op<"op_with_shaped_type_infer_type_adaptor_if",913              [InferTensorTypeAdaptorWithReify]> {914  let arguments = (ins AnyTensor:$operand1, AnyTensor:$operand2);915  let results = (outs AnyTensor:$result);916}917 918def OpWithResultShapeInterfaceOp : TEST_Op<"op_with_result_shape_interface",919      [DeclareOpInterfaceMethods<InferShapedTypeOpInterface,920          ["reifyReturnTypeShapes"]>]> {921  let arguments = (ins AnyRankedTensor:$operand1, AnyRankedTensor:$operand2);922  let results = (outs AnyRankedTensor:$result1, AnyRankedTensor:$result2);923}924 925def ReifyShapedTypeUsingReifyResultShapesOp :926    TEST_Op<"reify_shaped_type_using_reify_result_shapes",927        [DeclareOpInterfaceMethods<ReifyRankedShapedTypeOpInterface, 928            ["reifyResultShapes"]>]> {929  let description = [{930    Test that when resolving a single dimension of a result for an operation931    that doesnt implement `reifyShapeOfResult` nor implements `reifyDimOfResult`932    calls into the implementation of `reifyResultShapes` to get the required value.933    The op semantics is that the first result has the same shape as the second operand934    and the second result has the same shape as the first operand.935  }];936  let arguments = (ins AnyRankedTensor:$operand1, AnyRankedTensor:$operand2);937  let results = (outs AnyRankedTensor:$result1, AnyRankedTensor:$result2);938}939 940def ReifyShapedTypeUsingReifyShapeOfResultOp :941    TEST_Op<"reify_shaped_type_using_reify_shape_of_result",942        [DeclareOpInterfaceMethods<ReifyRankedShapedTypeOpInterface, 943            ["reifyResultShapes", "reifyShapeOfResult"]>]> {944  let description = [{945    Test that when resolving a single dimension of a result for an operation946    that doesnt implement `reifyDimOfResult` but implements `reifyShapeOfResult`, which947    is used to get the required value. `reifyResultShapes` is implemented as a failure948    (which is also the default implementation) to ensure it is not called.949    The op semantics is that the first result has the same shape as the second operand950    and the second result has the same shape as the first operand.951  }];952  let arguments = (ins AnyRankedTensor:$operand1, AnyRankedTensor:$operand2);953  let results = (outs AnyRankedTensor:$result1, AnyRankedTensor:$result2);954}955 956def ReifyShapedTypeUsingReifyDimOfResultOp :957    TEST_Op<"reify_shaped_type_using_reify_dim_of_result",958        [DeclareOpInterfaceMethods<ReifyRankedShapedTypeOpInterface, 959            ["reifyResultShapes", "reifyShapeOfResult", "reifyDimOfResult"]>]> {960  let description = [{961    Test that when resolving a single dimension of a result for an operation962    that implements `reifyDimOfResult`, which is used to get the required value.963    `reifyResultShapes` and `reifyShapeOfResult` are implemented as failures964    to ensure they are not called. The op semantics is that the first result has965    the same shape as the second operand and the second result has the same shape966    as the first operand.967  }];968  let arguments = (ins AnyRankedTensor:$operand1, AnyRankedTensor:$operand2);969  let results = (outs AnyRankedTensor:$result1, AnyRankedTensor:$result2);970}971 972def UnreifiableResultShapesOp : TEST_Op<"unreifiable_result_shapes",973    [DeclareOpInterfaceMethods<ReifyRankedShapedTypeOpInterface,974        ["reifyResultShapes"]>]> {975  let description = [{976    Test handling of case where some dimension of the result cannot be977    reified. This tests the path when `reifyResultShapes` is implemented.978 979    Expected that dim 0 of `result` is reifable as dim 0 of `operand`, but980    dim 1 of `result` is not reifiable.981  }];982  let arguments = (ins 2DTensorOf<[AnyType]>:$operand);983  let results = (outs 2DTensorOf<[AnyType]>:$result);984}985 986def UnreifiableResultShapeOp : TEST_Op<"unreifiable_result_shape",987    [DeclareOpInterfaceMethods<ReifyRankedShapedTypeOpInterface,988        ["reifyResultShapes", "reifyShapeOfResult"]>]> {989  let description = [{990    Test handling of case where some dimension of the result cannot be991    reified. This tests the path when `reifyShapeOfResult` is implemented,992    but not `reifyDimOfResult` with `reifyResultShapes` implemented as a failure.993 994    Expected that dim 0 of `result` is reifable as dim 0 of `operand`, but995    dim 1 of `result` is not reifiable.996  }];997  let arguments = (ins 2DTensorOf<[AnyType]>:$operand);998  let results = (outs 2DTensorOf<[AnyType]>:$result);999}1000 1001def UnreifiableDimOfResultShapeOp : TEST_Op<"unreifiable_dim_of_result_shape",1002    [DeclareOpInterfaceMethods<ReifyRankedShapedTypeOpInterface,1003        ["reifyResultShapes", "reifyShapeOfResult", "reifyDimOfResult"]>]> {1004  let description = [{1005    Test handling of case where some dimension of the result cannot be1006    reified. This tests the path when `reifyDimOfResult` is implemented,1007    and `reifyDimOfResult` with `reifyResultShapes` are implemented as a failure.1008 1009    Expected that dim 0 of `result` is reifable as dim 0 of `operand`, but1010    dim 1 of `result` is not reifiable.1011  }];1012  let arguments = (ins 2DTensorOf<[AnyType]>:$operand);1013  let results = (outs 2DTensorOf<[AnyType]>:$result);1014}1015 1016def IsNotScalar : Constraint<CPred<"$0.getType().getRank() != 0">>;1017 1018def UpdateAttr : Pat<(I32ElementsAttrOp $attr),1019                     (I32ElementsAttrOp ConstantAttr<I32ElementsAttr, "0">),1020                     [(IsNotScalar $attr)]>;1021 1022def TestBranchOp : TEST_Op<"br",1023    [DeclareOpInterfaceMethods<BranchOpInterface>, Terminator]> {1024  let arguments = (ins Variadic<AnyType>:$targetOperands);1025  let successors = (successor AnySuccessor:$target);1026}1027 1028def TestProducingBranchOp : TEST_Op<"producing_br",1029    [DeclareOpInterfaceMethods<BranchOpInterface>, Terminator,1030     AttrSizedOperandSegments]> {1031  let arguments = (ins Variadic<AnyType>:$firstOperands,1032                       Variadic<AnyType>:$secondOperands);1033  let results = (outs I32:$dummy);1034  let successors = (successor AnySuccessor:$first,AnySuccessor:$second);1035}1036 1037// Produces an error value on the error path1038def TestInternalBranchOp : TEST_Op<"internal_br",1039    [DeclareOpInterfaceMethods<BranchOpInterface>, Terminator,1040     AttrSizedOperandSegments]> {1041 1042  let arguments = (ins Variadic<AnyType>:$successOperands,1043                       Variadic<AnyType>:$errorOperands);1044 1045  let successors = (successor AnySuccessor:$successPath, AnySuccessor:$errorPath);1046}1047 1048def AttrSizedOperandOp : TEST_Op<"attr_sized_operands",1049                                 [AttrSizedOperandSegments]> {1050  let arguments = (ins1051    Variadic<I32>:$a,1052    Variadic<I32>:$b,1053    I32:$c,1054    Variadic<I32>:$d1055  );1056}1057 1058def AttrSizedResultOp : TEST_Op<"attr_sized_results",1059                                [AttrSizedResultSegments]> {1060  let results = (outs1061    Variadic<I32>:$a,1062    Variadic<I32>:$b,1063    I32:$c,1064    Variadic<I32>:$d1065  );1066}1067 1068def AttrSizedResultCompileTestOp : TEST_Op<"attr_sized_results_compile_test",1069                                           [AttrSizedResultSegments]> {1070  let results = (outs Variadic<I32>:$a, I32:$b, Optional<I32>:$c);1071}1072 1073 1074 1075// This is used to test encoding of a string attribute into an SSA name of a1076// pretty printed value name.1077def StringAttrPrettyNameOp1078 : TEST_Op<"string_attr_pretty_name",1079           [DeclareOpInterfaceMethods<OpAsmOpInterface, ["getAsmResultNames"]>]> {1080  let arguments = (ins StrArrayAttr:$names);1081  let results = (outs Variadic<I32>:$r);1082  let hasCustomAssemblyFormat = 1;1083}1084 1085 1086// This is used to test encoding of a string attribute into an SSA name of a1087// pretty printed value name.1088def CustomResultsNameOp1089 : TEST_Op<"custom_result_name",1090           [DeclareOpInterfaceMethods<OpAsmOpInterface, ["getAsmResultNames"]>]> {1091  let arguments = (ins1092    Variadic<AnyInteger>:$optional,1093    StrArrayAttr:$names1094  );1095  let results = (outs Variadic<AnyInteger>:$r);1096}1097 1098// This is used to test OpAsmTypeInterface::getAsmName for op result name,1099def ResultNameFromTypeOp1100 : TEST_Op<"result_name_from_type",1101           [DeclareOpInterfaceMethods<OpAsmOpInterface, ["getAsmResultNames"]>]> {1102  let results = (outs AnyType:$r);1103}1104 1105// This is used to test OpAsmTypeInterface::getAsmName for block argument,1106def BlockArgumentNameFromTypeOp1107  : TEST_Op<"block_argument_name_from_type",1108      [DeclareOpInterfaceMethods<OpAsmOpInterface, ["getAsmBlockArgumentNames"]>]> {1109  let regions = (region AnyRegion:$body);1110  let assemblyFormat = "regions attr-dict-with-keyword";1111}1112 1113// This is used to test OpAsmTypeInterface::getAsmName's integration with AsmPrinter1114// for op result name when OpAsmOpInterface::getAsmResultNames is the default implementation1115// i.e. does nothing.1116def ResultNameFromTypeInterfaceOp1117 : TEST_Op<"result_name_from_type_interface",1118           [OpAsmOpInterface]> {1119  let results = (outs Variadic<AnyType>:$r);1120}1121 1122// This is used to test OpAsmTypeInterface::getAsmName's integration with AsmPrinter1123// for block argument name when OpAsmOpInterface::getAsmBlockArgumentNames is the default implementation1124// i.e. does nothing.1125def BlockArgumentNameFromTypeInterfaceOp1126  : TEST_Op<"block_argument_name_from_type_interface",1127      [OpAsmOpInterface]> {1128  let regions = (region AnyRegion:$body);1129  let assemblyFormat = "regions attr-dict-with-keyword";1130}1131 1132// This is used to test the OpAsmOpInterface::getDefaultDialect() feature:1133// operations nested in a region under this op will drop the "test." dialect1134// prefix.1135def DefaultDialectOp : TEST_Op<"default_dialect", [OpAsmOpInterface]> {1136 let regions = (region AnyRegion:$body);1137  let extraClassDeclaration = [{1138    static ::llvm::StringRef getDefaultDialect() {1139      return "test";1140    }1141    void getAsmResultNames(::llvm::function_ref<void(::mlir::Value, ::llvm::StringRef)> setNameFn) {}1142  }];1143  let assemblyFormat = "regions attr-dict-with-keyword";1144}1145 1146 1147// This is used to test the OpAsmOpInterface::getAsmBlockName() feature:1148// blocks nested in a region under this op will have a name defined by the1149// interface.1150def AsmBlockNameOp : TEST_Op<"block_names", [OpAsmOpInterface]> {1151 let regions = (region AnyRegion:$body);1152  let extraClassDeclaration = [{1153    void getAsmBlockNames(mlir::OpAsmSetBlockNameFn setNameFn) {1154      std::string name;1155      int count = 0;1156      for (::mlir::Block &block : getRegion().getBlocks()) {1157        name = "foo" + std::to_string(count++);1158        setNameFn(&block, name);1159      }1160    }1161  }];1162  let assemblyFormat = "regions attr-dict-with-keyword";1163}1164 1165// This operation requires its return type to have the trait 'TestTypeTrait'.1166def ResultTypeWithTraitOp : TEST_Op<"result_type_with_trait", []> {1167  let results = (outs AnyType);1168  let hasVerifier = 1;1169}1170 1171// This operation requires its "attr" attribute to have the1172// trait 'TestAttrTrait'.1173def AttrWithTraitOp : TEST_Op<"attr_with_trait", []> {1174  let arguments = (ins AnyAttr:$attr);1175  let hasVerifier = 1;1176}1177 1178//===----------------------------------------------------------------------===//1179// Test Locations1180//===----------------------------------------------------------------------===//1181 1182def TestLocationSrcOp : TEST_Op<"loc_src"> {1183  let arguments = (ins I32:$input);1184  let results = (outs I32:$output);1185}1186 1187def TestLocationDstOp : TEST_Op<"loc_dst", [SameOperandsAndResultType]> {1188  let arguments = (ins I32:$input);1189  let results = (outs I32:$output);1190}1191 1192def TestLocationSrcNoResOp : TEST_Op<"loc_src_no_res"> {1193  let arguments = (ins I32:$input);1194  let results = (outs);1195}1196 1197def TestLocationDstNoResOp : TEST_Op<"loc_dst_no_res"> {1198  let arguments = (ins I32:$input);1199  let results = (outs);1200}1201 1202def TestLocationAttrOp : TEST_Op<"op_with_loc_attr"> {1203  let arguments = (ins LocationAttr:$loc_attr);1204  let results = (outs );1205  let assemblyFormat = "$loc_attr attr-dict";1206}1207 1208//===----------------------------------------------------------------------===//1209// Test Patterns1210//===----------------------------------------------------------------------===//1211 1212def OpA : TEST_Op<"op_a"> {1213  let arguments = (ins I32, I32Attr:$attr);1214  let results = (outs I32);1215}1216 1217def OpB : TEST_Op<"op_b"> {1218  let arguments = (ins I32, I32Attr:$attr);1219  let results = (outs I32);1220}1221 1222// Test named pattern.1223def TestNamedPatternRule : Pat<(OpA $input, $attr), (OpB $input, $attr)>;1224 1225// Test with fused location.1226def : Pat<(OpA (OpA $input, $attr), $bttr), (OpB $input, $bttr)>;1227 1228// Test added benefit.1229def OpD : TEST_Op<"op_d">, Arguments<(ins I32)>, Results<(outs I32)>;1230def OpE : TEST_Op<"op_e">, Arguments<(ins I32)>, Results<(outs I32)>;1231def OpF : TEST_Op<"op_f">, Arguments<(ins I32)>, Results<(outs I32)>;1232def OpG : TEST_Op<"op_g">, Arguments<(ins I32)>, Results<(outs I32)>;1233// Verify that bumping benefit results in selecting different op.1234def : Pat<(OpD $input), (OpE $input)>;1235def : Pat<(OpD $input), (OpF $input), [], [], (addBenefit 10)>;1236// Verify that patterns with more source nodes are selected before those with fewer.1237def : Pat<(OpG $input), (OpB $input, ConstantAttr<I32Attr, "20">:$attr)>;1238def : Pat<(OpG (OpG $input)), (OpB $input, ConstantAttr<I32Attr, "34">:$attr)>;1239 1240// Test patterns for zero-result op.1241def OpH : TEST_Op<"op_h">, Arguments<(ins I32)>, Results<(outs)>;1242def OpI : TEST_Op<"op_i">, Arguments<(ins I32)>, Results<(outs)>;1243def : Pat<(OpH $input), (OpI $input)>;1244 1245// Test patterns for zero-input op.1246def OpJ : TEST_Op<"op_j">, Arguments<(ins)>, Results<(outs I32)>;1247def OpK : TEST_Op<"op_k">, Arguments<(ins)>, Results<(outs I32)>;1248def : Pat<(OpJ), (OpK)>;1249 1250// Test that natives calls are only called once during rewrites.1251def OpM : TEST_Op<"op_m"> {1252  let arguments = (ins I32, OptionalAttr<I32Attr>:$optional_attr);1253  let results = (outs I32);1254}1255 1256def OpN : TEST_Op<"op_n"> {1257  let arguments = (ins I32, I32);1258  let results = (outs I32);1259}1260 1261def OpO : TEST_Op<"op_o"> {1262  let arguments = (ins I32);1263  let results = (outs I32);1264}1265 1266def OpP : TEST_Op<"op_p"> {1267  let arguments = (ins I32, I32, I32, I32, I32, I32);1268  let results = (outs I32);1269}1270 1271def OpQ : TEST_Op<"op_q"> {1272  let arguments = (ins AnyType, AnyType);1273  let results = (outs AnyType);1274}1275 1276// Test constant-folding a pattern that maps `(F32) -> SI32`.1277def SignOp : TEST_Op<"sign", [SameOperandsAndResultShape]> {1278  let arguments = (ins RankedTensorOf<[F32]>:$operand);1279  let results = (outs RankedTensorOf<[SI32]>:$result);1280 1281  let assemblyFormat = [{1282    $operand attr-dict `:` functional-type(operands, results)1283  }];1284}1285 1286// Test constant-folding a pattern that maps `(F32, F32) -> I1`.1287def LessThanOp : TEST_Op<"less_than", [SameOperandsAndResultShape]> {1288  let arguments = (ins RankedTensorOf<[F32]>:$lhs, RankedTensorOf<[F32]>:$rhs);1289  let results = (outs RankedTensorOf<[I1]>:$result);1290 1291  let assemblyFormat = [{1292    $lhs `,` $rhs attr-dict `:` functional-type(operands, results)1293  }];1294}1295 1296// Test same operand name enforces equality condition check.1297def TestEqualArgsPattern : Pat<(OpN $a, $a), (OpO $a)>;1298 1299// Test when equality is enforced at different depth.1300def TestNestedOpEqualArgsPattern :1301  Pat<(OpN $b, (OpP $a, $b, $c, $d, $e, $f)), (replaceWithValue $b)>;1302 1303// Test when equality is enforced on same op and same operand but at different1304// depth. We only bound one of the $x to the second operand of outer OpN and1305// left another be the default value (which is the value of first operand of1306// outer OpN). As a result, it ended up comparing wrong values in some cases.1307def TestNestedSameOpAndSameArgEqualityPattern :1308  Pat<(OpN (OpN $_, $x), $x), (replaceWithValue $x)>;1309 1310// Test multiple equal arguments check enforced.1311def TestMultipleEqualArgsPattern :1312  Pat<(OpP $a, $b, $a, $a, $b, $c), (OpN $c, $b)>;1313 1314// Test equal arguments checks are applied before user provided constraints.1315def AssertBinOpEqualArgsAndReturnTrue : Constraint<1316  CPred<"assertBinOpEqualArgsAndReturnTrue($0)">>;1317def TestEqualArgsCheckBeforeUserConstraintsPattern :1318  Pat<(OpQ:$op $x, $x),1319      (replaceWithValue $x),1320      [(AssertBinOpEqualArgsAndReturnTrue $op)]>;1321 1322// Test for memrefs normalization of an op with normalizable memrefs.1323def OpNorm : TEST_Op<"op_norm", [MemRefsNormalizable]> {1324  let arguments = (ins AnyMemRef:$X, AnyMemRef:$Y);1325}1326// Test for memrefs normalization of an op without normalizable memrefs.1327def OpNonNorm : TEST_Op<"op_nonnorm"> {1328  let arguments = (ins AnyMemRef:$X, AnyMemRef:$Y);1329}1330// Test for memrefs normalization of an op that has normalizable memref results.1331def OpNormRet : TEST_Op<"op_norm_ret", [MemRefsNormalizable]> {1332  let arguments = (ins AnyMemRef:$X);1333  let results = (outs AnyMemRef:$Y, AnyMemRef:$Z);1334}1335 1336// Test for memrefs normalization of an op with a reference to a function1337// symbol.1338def OpFuncRef : TEST_Op<"op_funcref"> {1339  let summary = "Test op with a reference to a function symbol";1340  let description = [{1341    The "test.op_funcref" is a test op with a reference to a function symbol.1342  }];1343}1344 1345// Pattern add the argument plus a increasing static number hidden in1346// OpMTest function. That value is set into the optional argument.1347// That way, we will know if operations is called once or twice.1348def OpMGetNullAttr : NativeCodeCall<"Attribute()">;1349def OpMAttributeIsNull : Constraint<CPred<"! ($_self)">, "Attribute is null">;1350def OpMVal : NativeCodeCall<"opMTest($_builder, $0)">;1351def : Pat<(OpM $attr, $optAttr), (OpM $attr, (OpMVal $attr) ),1352    [(OpMAttributeIsNull:$optAttr)]>;1353 1354// Test `$_` for ignoring op argument match.1355def TestIgnoreArgMatchSrcOp : TEST_Op<"ignore_arg_match_src"> {1356  let arguments = (ins1357    AnyType:$a, AnyType:$b, AnyType:$c,1358    AnyAttr:$d, AnyAttr:$e, AnyAttr:$f);1359}1360def TestIgnoreArgMatchDstOp : TEST_Op<"ignore_arg_match_dst"> {1361  let arguments = (ins AnyType:$b, AnyAttr:$f);1362}1363def : Pat<(TestIgnoreArgMatchSrcOp $_, $b, I32, I64Attr:$_, $_, $f),1364          (TestIgnoreArgMatchDstOp $b, $f)>;1365 1366def OpInterleavedOperandAttribute1 : TEST_Op<"interleaved_operand_attr1"> {1367  let arguments = (ins1368    I32:$input1,1369    I64Attr:$attr1,1370    I32:$input2,1371    I64Attr:$attr21372  );1373}1374 1375def OpInterleavedOperandAttribute2 : TEST_Op<"interleaved_operand_attr2"> {1376  let arguments = (ins1377    I32:$input1,1378    I64Attr:$attr1,1379    I32:$input2,1380    I64Attr:$attr21381  );1382}1383 1384def ManyArgsOp : TEST_Op<"many_arguments"> {1385  let arguments = (ins1386    I32:$input1, I32:$input2, I32:$input3, I32:$input4, I32:$input5,1387    I32:$input6, I32:$input7, I32:$input8, I32:$input9,1388    I64Attr:$attr1, I64Attr:$attr2, I64Attr:$attr3, I64Attr:$attr4,1389    I64Attr:$attr5, I64Attr:$attr6, I64Attr:$attr7, I64Attr:$attr8,1390    I64Attr:$attr91391  );1392}1393 1394// Test that DRR does not blow up when seeing lots of arguments.1395def : Pat<(ManyArgsOp1396            $input1, $input2, $input3, $input4, $input5,1397            $input6, $input7, $input8, $input9,1398            ConstantAttr<I64Attr, "42">,1399            $attr2, $attr3, $attr4, $attr5, $attr6,1400            $attr7, $attr8, $attr9),1401          (ManyArgsOp1402            $input1, $input2, $input3, $input4, $input5,1403            $input6, $input7, $input8, $input9,1404            ConstantAttr<I64Attr, "24">,1405            $attr2, $attr3, $attr4, $attr5, $attr6,1406            $attr7, $attr8, $attr9)>;1407 1408// Test that we can capture and reference interleaved operands and attributes.1409def : Pat<(OpInterleavedOperandAttribute1 $input1, $attr1, $input2, $attr2),1410          (OpInterleavedOperandAttribute2 $input1, $attr1, $input2, $attr2)>;1411 1412// Test NativeCodeCall.1413def OpNativeCodeCall1 : TEST_Op<"native_code_call1"> {1414  let arguments = (ins1415    I32:$input1, I32:$input2,1416    BoolAttr:$choice,1417    I64Attr:$attr1, I64Attr:$attr21418  );1419  let results = (outs I32);1420}1421def OpNativeCodeCall2 : TEST_Op<"native_code_call2"> {1422  let arguments = (ins I32:$input, I64ArrayAttr:$attr);1423  let results = (outs I32);1424}1425// Native code call to invoke a C++ function1426def CreateOperand: NativeCodeCall<"chooseOperand($0, $1, $2)">;1427// Native code call to invoke a C++ expression1428def CreateArrayAttr: NativeCodeCall<"$_builder.getArrayAttr({$0, $1})">;1429// Test that we can use NativeCodeCall to create operand and attribute.1430// This pattern chooses between $input1 and $input2 according to $choice and1431// it combines $attr1 and $attr2 into an array attribute.1432def : Pat<(OpNativeCodeCall1 $input1, $input2,1433                             ConstBoolAttrTrue:$choice, $attr1, $attr2),1434          (OpNativeCodeCall2 (CreateOperand $input1, $input2, $choice),1435                             (CreateArrayAttr $attr1, $attr2))>;1436// Note: the following is just for testing purpose.1437// Should use the replaceWithValue directive instead.1438def UseOpResult: NativeCodeCall<"$0">;1439// Test that we can use NativeCodeCall to create result.1440def : Pat<(OpNativeCodeCall1 $input1, $input2,1441                             ConstBoolAttrFalse, $attr1, $attr2),1442          (UseOpResult $input2)>;1443 1444def OpNativeCodeCall3 : TEST_Op<"native_code_call3"> {1445  let arguments = (ins I32:$input);1446  let results = (outs I32);1447}1448// Test that NativeCodeCall is not ignored if it is not used to directly1449// replace the matched root op.1450def : Pattern<(OpNativeCodeCall3 $input),1451              [(NativeCodeCallVoid<"createOpI($_builder, $_loc, $0)"> $input),1452               (OpK)]>;1453 1454def OpNativeCodeCall4 : TEST_Op<"native_code_call4"> {1455  let arguments = (ins AnyType:$input1);1456  let results = (outs I32:$output1, I32:$output2);1457}1458def OpNativeCodeCall5 : TEST_Op<"native_code_call5"> {1459  let arguments = (ins I32:$input1, I32:$input2);1460  let results = (outs I32:$output1, I32:$output2);1461}1462 1463def GetFirstI32Result : NativeCodeCall<"success(getFirstI32Result($_self, $0))">;1464def BindNativeCodeCallResult : NativeCodeCall<"bindNativeCodeCallResult($0)">;1465def : Pat<(OpNativeCodeCall4 (GetFirstI32Result $ret)),1466          (OpNativeCodeCall5 (BindNativeCodeCallResult:$native $ret), $native)>;1467 1468def OpNativeCodeCall6 : TEST_Op<"native_code_call6"> {1469  let arguments = (ins I32:$input1, I32:$input2);1470  let results = (outs I32:$output1, I32:$output2);1471}1472def OpNativeCodeCall7 : TEST_Op<"native_code_call7"> {1473  let arguments = (ins I32:$input);1474  let results = (outs I32);1475}1476def BindMultipleNativeCodeCallResult : NativeCodeCall<"bindMultipleNativeCodeCallResult($0, $1)", 2>;1477def : Pattern<(OpNativeCodeCall6 $arg1, $arg2),1478              [(OpNativeCodeCall7 (BindMultipleNativeCodeCallResult:$native__0 $arg1, $arg2)),1479               (OpNativeCodeCall7 $native__1)]>;1480 1481// Test AllAttrOf.1482def OpAllAttrConstraint1 : TEST_Op<"all_attr_constraint_of1"> {1483  let arguments = (ins I64ArrayAttr:$attr);1484  let results = (outs I32);1485}1486def OpAllAttrConstraint2 : TEST_Op<"all_attr_constraint_of2"> {1487  let arguments = (ins I64ArrayAttr:$attr);1488  let results = (outs I32);1489}1490def Constraint0 : AttrConstraint<1491    CPred<"::llvm::cast<::mlir::IntegerAttr>(::llvm::cast<ArrayAttr>($_self)[0]).getInt() == 0">,1492    "[0] == 0">;1493def Constraint1 : AttrConstraint<1494    CPred<"::llvm::cast<::mlir::IntegerAttr>(::llvm::cast<ArrayAttr>($_self)[1]).getInt() == 1">,1495    "[1] == 1">;1496def : Pat<(OpAllAttrConstraint11497            AllAttrOf<[Constraint0, Constraint1]>:$attr),1498          (OpAllAttrConstraint2 $attr)>;1499 1500// Op for testing RewritePattern removing op with inner ops.1501def TestOpWithRegionPattern : TEST_Op<"op_with_region_pattern"> {1502  let regions = (region SizedRegion<1>:$region);1503  let hasCanonicalizer = 1;1504}1505 1506def TestOpConstant : TEST_Op<"constant", [ConstantLike, NoMemoryEffect]> {1507  let arguments = (ins AnyAttr:$value);1508  let results = (outs AnyType);1509 1510  let hasFolder = 1;1511}1512 1513def OpR : TEST_Op<"op_r">, Arguments<(ins AnyInteger, AnyInteger)>, Results<(outs AnyInteger)>;1514def OpS : TEST_Op<"op_s">, Arguments<(ins AnyInteger, AnyAttr:$value)>, Results<(outs AnyInteger)>;1515 1516def : Pat<(OpR $input1, (ConstantLikeMatcher I32Attr:$input2)),1517          (OpS:$unused $input1, $input2)>;1518 1519// Op for testing trivial removal via folding of op with inner ops and no uses.1520def TestOpWithRegionFoldNoMemoryEffect : TEST_Op<1521    "op_with_region_fold_no_side_effect", [NoMemoryEffect]> {1522  let regions = (region SizedRegion<1>:$region);1523}1524 1525// Op for testing folding of outer op with inner ops.1526def TestOpWithRegionFold : TEST_Op<"op_with_region_fold"> {1527  let arguments = (ins AnyType:$operand);1528  let results = (outs AnyType);1529  let regions = (region SizedRegion<1>:$region);1530  let hasFolder = 1;1531}1532 1533def TestOpWithVariadicResultsAndFolder: TEST_Op<"op_with_variadic_results_and_folder"> {1534  let arguments = (ins Variadic<I32>);1535  let results = (outs Variadic<I32>);1536  let hasFolder = 1;1537}1538 1539def TestAddIOp : TEST_Op<"addi"> {1540  let arguments = (ins AnyTypeOf<[I32, TestI32]>:$op1,1541                       AnyTypeOf<[I32, TestI32]>:$op2);1542  let results = (outs AnyTypeOf<[I32, TestI32]>);1543}1544 1545def TestCommutativeOp : TEST_Op<"op_commutative", [Commutative]> {1546  let arguments = (ins I32:$op1, I32:$op2, I32:$op3, I32:$op4);1547  let results = (outs I32);1548}1549 1550def TestLargeCommutativeOp : TEST_Op<"op_large_commutative", [Commutative]> {1551  let arguments = (ins I32:$op1, I32:$op2, I32:$op3, I32:$op4, I32:$op5, I32:$op6, I32:$op7);1552  let results = (outs I32);1553}1554 1555def TestCommutative2Op : TEST_Op<"op_commutative2", [Commutative]> {1556  let arguments = (ins I32:$op1, I32:$op2);1557  let results = (outs I32);1558}1559 1560def TestIdempotentTraitOp1561 : TEST_Op<"op_idempotent_trait",1562           [SameOperandsAndResultType, NoMemoryEffect, Idempotent]> {1563  let arguments = (ins I32:$op1);1564  let results = (outs I32);1565}1566 1567def TestIdempotentTraitBinaryOp1568    : TEST_Op<"op_idempotent_trait_binary",1569              [SameOperandsAndResultType, NoMemoryEffect, Idempotent]> {1570  let arguments = (ins I32:$op1, I32:$op2);1571  let results = (outs I32);1572}1573 1574def TestInvolutionTraitNoOperationFolderOp1575 : TEST_Op<"op_involution_trait_no_operation_fold",1576           [SameOperandsAndResultType, NoMemoryEffect, Involution]> {1577  let arguments = (ins I32:$op1);1578  let results = (outs I32);1579}1580 1581def TestInvolutionTraitFailingOperationFolderOp1582 : TEST_Op<"op_involution_trait_failing_operation_fold",1583           [SameOperandsAndResultType, NoMemoryEffect, Involution]> {1584  let arguments = (ins I32:$op1);1585  let results = (outs I32);1586  let hasFolder = 1;1587}1588 1589def TestInvolutionTraitSuccesfulOperationFolderOp1590 : TEST_Op<"op_involution_trait_succesful_operation_fold",1591           [SameOperandsAndResultType, NoMemoryEffect, Involution]> {1592  let arguments = (ins I32:$op1);1593  let results = (outs I32);1594  let hasFolder = 1;1595}1596 1597def TestOpInPlaceFoldAnchor : TEST_Op<"op_in_place_fold_anchor"> {1598  let arguments = (ins I32);1599  let results = (outs I32);1600}1601 1602def TestOpInPlaceFold : TEST_Op<"op_in_place_fold"> {1603  let arguments = (ins I32:$op, OptionalAttr<I32Attr>:$attr);1604  let results = (outs I32);1605  let hasFolder = 1;1606}1607 1608def TestOpInPlaceSelfFold : TEST_Op<"op_in_place_self_fold"> {1609  let arguments = (ins UnitAttr:$folded);1610  let results = (outs I32);1611  let hasFolder = 1;1612}1613def : Pat<(TestOpInPlaceSelfFold:$op $_),1614          (TestOpConstant ConstantAttr<I32Attr, "97">)>;1615 1616// Test op that simply returns success.1617def TestOpInPlaceFoldSuccess : TEST_Op<"op_in_place_fold_success"> {1618  let results = (outs Variadic<I1>);1619  let hasFolder = 1;1620  let extraClassDefinition = [{1621    ::llvm::LogicalResult $cppClass::fold(FoldAdaptor adaptor,1622        SmallVectorImpl<OpFoldResult> &results) {1623      return success();1624    }1625  }];1626}1627 1628def TestOpFoldWithFoldAdaptor1629  : TEST_Op<"fold_with_fold_adaptor",1630      [AttrSizedOperandSegments, NoTerminator]> {1631  let arguments = (ins1632    I32:$op,1633    DenseI32ArrayAttr:$attr,1634    Variadic<I32>:$variadic,1635    VariadicOfVariadic<I32, "attr">:$var_of_var1636  );1637 1638  let results = (outs I32:$res);1639 1640  let regions = (region AnyRegion:$body);1641 1642  let assemblyFormat = [{1643    $op `,` `[` $variadic `]` `,` `{` $var_of_var `}` $body attr-dict-with-keyword1644  }];1645 1646  let hasFolder = 1;1647}1648 1649def TestDialectCanonicalizerOp : TEST_Op<"dialect_canonicalizable"> {1650  let arguments = (ins);1651  let results = (outs I32);1652}1653 1654//===----------------------------------------------------------------------===//1655// Test Patterns (Symbol Binding)1656//===----------------------------------------------------------------------===//1657 1658// Test symbol binding.1659def OpSymbolBindingA : TEST_Op<"symbol_binding_a", []> {1660  let arguments = (ins I32:$operand, I64Attr:$attr);1661  let results = (outs I32);1662}1663def OpSymbolBindingB : TEST_Op<"symbol_binding_b", []> {1664  let arguments = (ins I32:$operand);1665  let results = (outs I32);1666}1667def OpSymbolBindingC : TEST_Op<"symbol_binding_c", []> {1668  let arguments = (ins I32:$operand);1669  let results = (outs I32);1670  let builders = OpSymbolBindingB.builders;1671}1672def OpSymbolBindingD : TEST_Op<"symbol_binding_d", []> {1673  let arguments = (ins I32:$input1, I32:$input2, I64Attr:$attr);1674  let results = (outs I32);1675}1676def HasOneUse: Constraint<CPred<"$0.hasOneUse()">, "has one use">;1677def : Pattern<1678    // Bind to source pattern op operand/attribute/result1679    (OpSymbolBindingA:$res_a $operand, $attr), [1680        // Bind to auxiliary op result1681        (OpSymbolBindingC:$res_c (OpSymbolBindingB:$res_b $operand)),1682 1683        // Use bound symbols in resultant ops1684        (OpSymbolBindingD $res_b, $res_c, $attr)],1685    // Use bound symbols in additional constraints1686    [(HasOneUse $res_a)]>;1687 1688def OpSymbolBindingNoResult : TEST_Op<"symbol_binding_no_result", []> {1689  let arguments = (ins I32:$operand);1690}1691 1692// Test that we can bind to an op without results and reference it later.1693def : Pat<(OpSymbolBindingNoResult:$op $operand),1694          (NativeCodeCallVoid<"handleNoResultOp($_builder, $0)"> $op)>;1695 1696//===----------------------------------------------------------------------===//1697// Test Patterns (Attributes)1698//===----------------------------------------------------------------------===//1699 1700// Test matching against op attributes.1701def OpAttrMatch1 : TEST_Op<"match_op_attribute1"> {1702  let arguments = (ins1703    I32Attr:$required_attr,1704    OptionalAttr<I32Attr>:$optional_attr,1705    DefaultValuedAttr<I32Attr, "42">:$default_valued_attr,1706    I32Attr:$more_attr1707  );1708  let results = (outs I32);1709}1710def OpAttrMatch2 : TEST_Op<"match_op_attribute2"> {1711  let arguments = OpAttrMatch1.arguments;1712  let results = (outs I32);1713}1714def MoreConstraint : AttrConstraint<1715    CPred<"::llvm::cast<IntegerAttr>($_self).getInt() == 4">, "more constraint">;1716def : Pat<(OpAttrMatch1 $required, $optional, $default_valued,1717                        MoreConstraint:$more),1718          (OpAttrMatch2 $required, $optional, $default_valued, $more)>;1719 1720// Test unit attrs.1721def OpAttrMatch3 : TEST_Op<"match_op_attribute3"> {1722  let arguments = (ins UnitAttr:$attr);1723  let results = (outs I32);1724}1725def OpAttrMatch4 : TEST_Op<"match_op_attribute4"> {1726  let arguments = (ins UnitAttr:$attr1, UnitAttr:$attr2);1727  let results = (outs I32);1728}1729def : Pat<(OpAttrMatch3 $attr), (OpAttrMatch4 ConstUnitAttr, $attr)>;1730 1731// Test with constant attr.1732def OpC : TEST_Op<"op_c">, Arguments<(ins I32)>, Results<(outs I32)>;1733def : Pat<(OpC $input), (OpB $input, ConstantAttr<I32Attr, "17">:$attr)>;1734 1735// Test integer enum attribute in rewrites.1736def : Pat<(I32EnumAttrOp I32Case5), (I32EnumAttrOp I32Case10)>;1737def : Pat<(I64EnumAttrOp I64Case5), (I64EnumAttrOp I64Case10)>;1738 1739def ThreeResultOp : TEST_Op<"three_result"> {1740  let arguments = (ins MultiResultOpEnum:$kind);1741  let results = (outs I32:$result1, F32:$result2, F32:$result3);1742}1743 1744def AnotherThreeResultOp1745    : TEST_Op<"another_three_result",1746              [DeclareOpInterfaceMethods<InferTypeOpInterface>]> {1747  let arguments = (ins MultiResultOpEnum:$kind);1748  let results = (outs I32:$result1, F32:$result2, F32:$result3);1749}1750 1751def TwoResultOp : TEST_Op<"two_result"> {1752  let arguments = (ins MultiResultOpEnum:$kind);1753  let results = (outs I32:$result1, F32:$result2);1754}1755 1756def AnotherTwoResultOp : TEST_Op<"another_two_result"> {1757  let arguments = (ins MultiResultOpEnum:$kind);1758  let results = (outs F32:$result1, F32:$result2);1759}1760 1761def OneResultOp1 : TEST_Op<"one_result1"> {1762  let arguments = (ins MultiResultOpEnum:$kind);1763  let results = (outs F32:$result1);1764}1765 1766def OneResultOp2 : TEST_Op<"one_result2"> {1767  let arguments = (ins MultiResultOpEnum:$kind);1768  let results = (outs I32:$result1);1769}1770 1771def OneResultOp3 : TEST_Op<"one_result3"> {1772  let arguments = (ins F32);1773  let results = (outs I32:$result1);1774}1775 1776// Test using multi-result op as a whole1777def : Pat<(ThreeResultOp MultiResultOpKind1:$kind),1778          (AnotherThreeResultOp $kind)>;1779 1780// Test using multi-result op as a whole for partial replacement1781def : Pattern<(ThreeResultOp MultiResultOpKind2:$kind),1782              [(TwoResultOp $kind),1783               (OneResultOp1 $kind)]>;1784def : Pattern<(ThreeResultOp MultiResultOpKind3:$kind),1785              [(OneResultOp2 $kind),1786               (AnotherTwoResultOp $kind)]>;1787 1788// Test using results separately in a multi-result op1789def : Pattern<(ThreeResultOp MultiResultOpKind4:$kind),1790              [(TwoResultOp:$res1__0 $kind),1791               (OneResultOp1 $kind),1792               (TwoResultOp:$res2__1 $kind)]>;1793 1794// Test referencing a single value in the value pack1795// This rule only matches TwoResultOp if its second result has no use.1796def : Pattern<(TwoResultOp:$res MultiResultOpKind5:$kind),1797              [(OneResultOp2 $kind),1798               (OneResultOp1 $kind)],1799              [(HasNoUseOf:$res__1)]>;1800 1801// Test using auxiliary ops for replacing multi-result op1802def : Pattern<1803    (ThreeResultOp MultiResultOpKind6:$kind), [1804        // Auxiliary op generated to help building the final result but not1805        // directly used to replace the source op's results.1806        (TwoResultOp:$interm $kind),1807 1808        (OneResultOp3 $interm__1),1809        (AnotherTwoResultOp $kind)1810    ]>;1811 1812//===----------------------------------------------------------------------===//1813// Test Patterns (Variadic Ops)1814//===----------------------------------------------------------------------===//1815 1816def OneVResOneVOperandOp1 : TEST_Op<"one_variadic_out_one_variadic_in1"> {1817  let arguments = (ins Variadic<I32>);1818  let results = (outs Variadic<I32>);1819}1820def OneVResOneVOperandOp2 : TEST_Op<"one_variadic_out_one_variadic_in2"> {1821  let arguments = (ins Variadic<I32>);1822  let results = (outs Variadic<I32>);1823}1824 1825// Rewrite an op with one variadic operand and one variadic result to1826// another similar op.1827def : Pat<(OneVResOneVOperandOp1 $inputs), (OneVResOneVOperandOp2 $inputs)>;1828 1829def MixedVOperandOp1 : TEST_Op<"mixed_variadic_in1",1830                               [SameVariadicOperandSize]> {1831  let arguments = (ins1832    Variadic<I32>:$input1,1833    F32:$input2,1834    Variadic<I32>:$input31835  );1836}1837 1838def MixedVOperandOp2 : TEST_Op<"mixed_variadic_in2",1839                               [SameVariadicOperandSize]> {1840  let arguments = (ins1841    Variadic<I32>:$input1,1842    F32:$input2,1843    Variadic<I32>:$input31844  );1845}1846 1847// Rewrite an op with both variadic operands and normal operands.1848def : Pat<(MixedVOperandOp1 $input1, $input2, $input3),1849          (MixedVOperandOp2 $input1, $input2, $input3)>;1850 1851def MixedVResultOp1 : TEST_Op<"mixed_variadic_out1", [SameVariadicResultSize]> {1852  let results = (outs1853    Variadic<I32>:$output1,1854    F32:$output2,1855    Variadic<I32>:$output31856  );1857}1858 1859def MixedVResultOp2 : TEST_Op<"mixed_variadic_out2", [SameVariadicResultSize]> {1860  let results = (outs1861    Variadic<I32>:$output1,1862    F32:$output2,1863    Variadic<I32>:$output31864  );1865}1866 1867// Rewrite an op with both variadic results and normal results.1868// Note that because we are generating the op with a top-level result pattern,1869// we are able to deduce the correct result types for the generated op using1870// the information from the matched root op.1871def : Pat<(MixedVResultOp1), (MixedVResultOp2)>;1872 1873def OneI32ResultOp : TEST_Op<"one_i32_out"> {1874  let results = (outs I32);1875}1876 1877def MixedVOperandOp3 : TEST_Op<"mixed_variadic_in3",1878                               [SameVariadicOperandSize]> {1879  let arguments = (ins1880    I32:$input1,1881    Variadic<I32>:$input2,1882    Variadic<I32>:$input3,1883    I32Attr:$count1884  );1885 1886  let results = (outs I32);1887}1888 1889def MixedVResultOp3 : TEST_Op<"mixed_variadic_out3",1890                               [SameVariadicResultSize]> {1891  let arguments = (ins I32Attr:$count);1892 1893  let results = (outs1894    I32:$output1,1895    Variadic<I32>:$output2,1896    Variadic<I32>:$output31897  );1898 1899  // We will use this op in a nested result pattern, where we cannot deduce the1900  // result type. So need to provide a builder not requiring result types.1901  let builders = [1902    OpBuilder<(ins "::mlir::IntegerAttr":$count),1903    [{1904      auto i32Type = $_builder.getIntegerType(32);1905      $_state.addTypes(i32Type); // $output11906      SmallVector<Type, 4> types(count.getInt(), i32Type);1907      $_state.addTypes(types); // $output21908      $_state.addTypes(types); // $output31909      $_state.addAttribute("count", count);1910    }]>1911  ];1912}1913 1914// Generates an op with variadic results using nested pattern.1915def : Pat<(OneI32ResultOp),1916          (MixedVOperandOp31917              (MixedVResultOp3:$results__0 ConstantAttr<I32Attr, "2">),1918              (replaceWithValue $results__1),1919              (replaceWithValue $results__2),1920              ConstantAttr<I32Attr, "2">)>;1921 1922// Variadic structured matching1923def MixedVOperandOp4 : TEST_Op<"mixed_variadic_in4"> {1924  let arguments = (ins1925    Variadic<I32>:$input1,1926    I32:$input2,1927    I32Attr:$attr11928  );1929}1930 1931def MixedVOperandOp5 : TEST_Op<"mixed_variadic_in5"> {1932  let arguments = (ins1933    I32:$input1,1934    I32:$input2,1935    I32:$input3,1936    I32Attr:$attr1,1937    StrAttr:$pattern_name1938  );1939}1940 1941// Helper op to test variadic recursive pattern matching1942def MixedVOperandInOutI32Op : TEST_Op<"mixed_variadic_in_out_i32"> {1943  let arguments = (ins1944    I32:$input1945  );1946  let results = (outs1947    I32:$output1948  );1949}1950 1951def : Pat<1952  (MixedVOperandOp4 (variadic $input1a, $input1b), $input2,1953                    ConstantAttr<I32Attr, "0">:$attr1),1954  (MixedVOperandOp5 $input1a, $input1b, $input2, $attr1,1955                    ConstantStrAttr<StrAttr, "MatchVariadic">)>;1956 1957def : Pat<1958  (MixedVOperandOp5 $input1a, $input1b, $input2, $attr1,1959                    ConstantStrAttr<StrAttr, "MatchInverseVariadic">),1960  (MixedVOperandOp3 $input2, (variadic $input1b), (variadic $input1a),1961                    ConstantAttr<I32Attr, "1">:$attr1)>;1962 1963def : Pat<1964  (MixedVOperandOp4 (variadic (MixedVOperandInOutI32Op $input1a),1965                              (MixedVOperandInOutI32Op $input1b)),1966                    $input2, ConstantAttr<I32Attr, "1">:$attr1),1967  (MixedVOperandOp5 $input1a, $input1b, $input2, $attr1,1968                    ConstantStrAttr<StrAttr, "MatchVariadicSubDag">)>;1969 1970def : Pat<1971  (MixedVOperandOp4 (variadic $input1, $input1), $input2,1972                    ConstantAttr<I32Attr, "2">:$attr1),1973  (MixedVOperandOp5 $input1, $input1, $input2, $attr1,1974                    ConstantStrAttr<StrAttr, "MatchVariadicSameSymbol">)>;1975 1976def MixedVOperandOp6 : TEST_Op<"mixed_variadic_in6",1977                               [SameVariadicOperandSize]> {1978  let arguments = (ins1979    Variadic<I32>:$input1,1980    Variadic<I32>:$input2,1981    I32Attr:$attr11982  );1983}1984 1985def : Pat<1986  (MixedVOperandOp6 (variadic:$input1 $input1a, $input1b),1987                    (variadic:$input2 $input2a, $input2b),1988                    ConstantAttr<I32Attr, "1">:$attr1),1989  (MixedVOperandOp6 $input2, $input1, ConstantAttr<I32Attr, "-1">)>;1990 1991def : Pat<1992  (MixedVOperandOp6 (variadic $input1a, $input1b),1993                    (variadic $input2a, $input2b),1994                    ConstantAttr<I32Attr, "2">:$attr1),1995  (MixedVOperandOp5 $input2a, $input2b, $input1b, $attr1,1996                    ConstantStrAttr<StrAttr, "MatchMultiVariadicSubSymbol">)>;1997 1998def MixedVOperandOp7 : TEST_Op<"mixed_variadic_optional_in7",1999                               [AttrSizedOperandSegments]> {2000  let arguments = (ins2001    Variadic<I32>:$input1,2002    Optional<I32>:$input2,2003    I32Attr:$attr12004  );2005}2006 2007def : Pat<2008  (MixedVOperandOp7 $input1, $input2, ConstantAttr<I32Attr, "2">:$attr1),2009  (MixedVOperandOp6 $input1, (variadic $input2), $attr1),2010  [(Constraint<CPred<"$0 != Value()">> $input2)]>;2011 2012//===----------------------------------------------------------------------===//2013// Test Patterns (either)2014//===----------------------------------------------------------------------===//2015 2016def TestEitherOpA : TEST_Op<"either_op_a"> {2017  let arguments = (ins AnyInteger:$arg0, AnyInteger:$arg1, AnyInteger:$arg2);2018  let results = (outs I32:$output);2019}2020 2021def TestEitherOpB : TEST_Op<"either_op_b"> {2022  let arguments = (ins AnyInteger:$arg0, AnyInteger:$arg1);2023  let results = (outs I32:$output);2024}2025 2026def TestEitherOpC : TEST_Op<"either_op_c"> {2027  let arguments = (ins AnyI32Attr:$attr, AnyInteger:$arg0, AnyInteger:$arg1);2028  let results = (outs I32:$output);2029}2030 2031def : Pat<(TestEitherOpA (either I32:$arg1, I16:$arg2), $x),2032          (TestEitherOpB $arg2, $x)>;2033 2034def : Pat<(TestEitherOpA (either (TestEitherOpB I32:$arg1, $_), I16:$arg2), $x),2035          (TestEitherOpB $arg2, $x)>;2036 2037def : Pat<(TestEitherOpA (either (TestEitherOpB I32:$arg1, $_),2038                                 (TestEitherOpB I16:$arg2, $_)),2039                          $x),2040          (TestEitherOpB $arg2, $x)>;2041 2042def : Pat<(TestEitherOpC ConstantAttr<I32Attr, "0">, (either $arg1, I32:$arg2)),2043          (TestEitherOpB $arg1, $arg2)>;2044 2045def TestEitherHelperOpA : TEST_Op<"either_helper_op_a"> {2046  let arguments = (ins I32:$arg0);2047  let results = (outs I32:$output);2048}2049 2050def TestEitherHelperOpB : TEST_Op<"either_helper_op_b"> {2051  let arguments = (ins I32:$arg0);2052  let results = (outs I32:$output);2053}2054 2055// This test case ensures `emitOpMatch` doesn't redefine `castedOp{0}` local2056// variables. To trigger this, we must ensure the matcher for2057// `TestEitherHelperOpA` and `TestEitherHelperOpB` are not lifted as a static2058// matcher.2059def : Pat<(TestEitherOpB (either (TestEitherHelperOpA I32:$either_helper_0),2060                                 (TestEitherHelperOpB I32:$either_helper_1))),2061          (TestEitherOpB $either_helper_0, $either_helper_1)>;2062 2063//===----------------------------------------------------------------------===//2064// Test Patterns (Location)2065//===----------------------------------------------------------------------===//2066 2067// Test that we can specify locations for generated ops.2068def : Pat<(TestLocationSrcOp:$res12069           (TestLocationSrcOp:$res22070            (TestLocationSrcOp:$res3 $input))),2071          (TestLocationDstOp2072            (TestLocationDstOp2073              (TestLocationDstOp $input, (location $res1)),2074              (location "named")),2075            (location "fused", $res2, $res3))>;2076 2077// Test that we can use the location of an op without results2078def : Pat<(TestLocationSrcNoResOp:$loc2079            (TestLocationSrcOp (TestLocationSrcOp $input))),2080          (TestLocationDstNoResOp $input, (location $loc))>;2081 2082//===----------------------------------------------------------------------===//2083// Test Patterns (Type Builders)2084//===----------------------------------------------------------------------===//2085 2086def SourceOp : TEST_Op<"source_op"> {2087  let arguments = (ins AnyInteger:$arg, AnyI32Attr:$tag);2088  let results = (outs AnyInteger);2089}2090 2091// An op without return type deduction.2092def OpX : TEST_Op<"op_x"> {2093  let arguments = (ins AnyInteger:$input);2094  let results = (outs AnyInteger);2095}2096 2097// Test that ops without built-in type deduction can be created in the2098// replacement DAG with an explicitly specified type.2099def : Pat<(SourceOp $val, ConstantAttr<I32Attr, "11">:$attr),2100          (OpX (OpX $val, (returnType "$_builder.getI32Type()")))>;2101// Test NativeCodeCall type builder can accept arguments.2102def SameTypeAs : NativeCodeCall<"$0.getType()">;2103 2104def : Pat<(SourceOp $val, ConstantAttr<I32Attr, "22">:$attr),2105          (OpX (OpX $val, (returnType (SameTypeAs $val))))>;2106 2107// Test multiple return types.2108def MakeI64Type : NativeCodeCall<"$_builder.getI64Type()">;2109def MakeI32Type : NativeCodeCall<"$_builder.getI32Type()">;2110 2111def OneToTwo : TEST_Op<"one_to_two"> {2112  let arguments = (ins AnyInteger);2113  let results = (outs AnyInteger, AnyInteger);2114}2115 2116def TwoToOne : TEST_Op<"two_to_one"> {2117  let arguments = (ins AnyInteger, AnyInteger);2118  let results = (outs AnyInteger);2119}2120 2121def : Pat<(SourceOp $val, ConstantAttr<I32Attr, "33">:$attr),2122          (TwoToOne (OpX (OneToTwo:$res__0 $val, (returnType (MakeI64Type), (MakeI32Type))), (returnType (MakeI32Type))),2123                    (OpX $res__1, (returnType (MakeI64Type))))>;2124 2125// Test copy value return type.2126def : Pat<(SourceOp $val, ConstantAttr<I32Attr, "44">:$attr),2127          (OpX (OpX $val, (returnType $val)))>;2128 2129// Test create multiple return types with different methods.2130def : Pat<(SourceOp $val, ConstantAttr<I32Attr, "55">:$attr),2131          (TwoToOne (OneToTwo:$res__0 $val, (returnType $val, "$_builder.getI64Type()")), $res__1)>;2132 2133//===----------------------------------------------------------------------===//2134// Test Patterns (Trailing Directives)2135//===----------------------------------------------------------------------===//2136 2137// Test that we can specify both `location` and `returnType` directives.2138def : Pat<(SourceOp $val, ConstantAttr<I32Attr, "66">:$attr),2139          (TwoToOne (OpX $val, (returnType $val), (location "loc1")),2140                    (OpX $val, (location "loc2"), (returnType $val)))>;2141 2142//===----------------------------------------------------------------------===//2143// Test Legalization2144//===----------------------------------------------------------------------===//2145 2146def Test_LegalizerEnum_Success : ConstantStrAttr<StrAttr, "Success">;2147def Test_LegalizerEnum_Failure : ConstantStrAttr<StrAttr, "Failure">;2148 2149def ILLegalOpA : TEST_Op<"illegal_op_a">, Results<(outs I32)>;2150def ILLegalOpB : TEST_Op<"illegal_op_b">, Results<(outs I32)>;2151def ILLegalOpC : TEST_Op<"illegal_op_c">, Results<(outs I32)>;2152def ILLegalOpD : TEST_Op<"illegal_op_d">, Results<(outs I32)>;2153def ILLegalOpE : TEST_Op<"illegal_op_e">, Results<(outs I32)>;2154def ILLegalOpF : TEST_Op<"illegal_op_f">, Results<(outs I32)>;2155def ILLegalOpG : TEST_Op<"illegal_op_g">, Results<(outs I32)>;2156def LegalOpA : TEST_Op<"legal_op_a">,2157  Arguments<(ins StrAttr:$status)>, Results<(outs I32)>;2158def LegalOpB : TEST_Op<"legal_op_b">, Results<(outs I32)>;2159def LegalOpC : TEST_Op<"legal_op_c">,2160  Arguments<(ins I32)>, Results<(outs I32)>;2161def LegalOpD : TEST_Op<"legal_op_d">, Arguments<(ins AnyType)>;2162 2163def ConvertBlockArgsOp : TEST_Op<"convert_block_args", [SingleBlock]> {2164  let arguments = (ins UnitAttr:$is_legal, UnitAttr:$replace_with_operand,2165                       UnitAttr:$duplicate, Optional<AnyType>:$val);2166  let regions = (region SizedRegion<1>:$body);2167  let assemblyFormat = [{2168    $val2169    (`is_legal` $is_legal^)?2170    (`duplicate` $duplicate^)?2171    (`replace_with_operand` $replace_with_operand^)?2172    $body attr-dict `:` functional-type(operands, results)2173  }];2174}2175 2176// Check that the conversion infrastructure can properly undo the creation of2177// operations where an operation was created before its parent, in this case,2178// in the parent's builder.2179def IllegalOpTerminator : TEST_Op<"illegal_op_terminator", [Terminator]>;2180def IllegalOpWithRegion : TEST_Op<"illegal_op_with_region"> {2181  let skipDefaultBuilders = 1;2182  let builders = [OpBuilder<(ins),2183    [{2184       Region *bodyRegion = $_state.addRegion();2185       OpBuilder::InsertionGuard g($_builder);2186       Block *body = $_builder.createBlock(bodyRegion);2187       $_builder.setInsertionPointToEnd(body);2188       IllegalOpTerminator::create($_builder,$_state.location);2189    }]>];2190}2191def IllegalOpWithRegionAnchor : TEST_Op<"illegal_op_with_region_anchor">;2192 2193// Check that smaller pattern depths are chosen, i.e. prioritize more direct2194// mappings.2195def : Pat<(ILLegalOpA), (LegalOpA Test_LegalizerEnum_Success)>;2196 2197def : Pat<(ILLegalOpA), (ILLegalOpB)>;2198def : Pat<(ILLegalOpB), (LegalOpA Test_LegalizerEnum_Failure)>;2199 2200// Check that the higher benefit pattern is taken for multiple legalizations2201// with the same depth.2202def : Pat<(ILLegalOpC), (ILLegalOpD)>;2203def : Pat<(ILLegalOpD), (LegalOpA Test_LegalizerEnum_Failure)>;2204 2205def : Pat<(ILLegalOpC), (ILLegalOpE), [], [], (addBenefit 10)>;2206def : Pat<(ILLegalOpE), (LegalOpA Test_LegalizerEnum_Success)>;2207 2208// Check that patterns use the most up-to-date value when being replaced.2209def TestRewriteOp : TEST_Op<"rewrite">,2210  Arguments<(ins AnyType)>, Results<(outs AnyType)>;2211def : Pat<(TestRewriteOp $input), (replaceWithValue $input)>;2212 2213// Check that patterns can specify bounded recursion when rewriting.2214def TestRecursiveRewriteOp : TEST_Op<"recursive_rewrite"> {2215  let arguments = (ins I64Attr:$depth);2216  let assemblyFormat = "$depth attr-dict";2217}2218 2219// Test legalization pattern: this op will be erase and will also erase the2220// producer of its operand.2221def BlackHoleOp : TEST_Op<"blackhole">,2222  Arguments<(ins AnyType)>;2223 2224//===----------------------------------------------------------------------===//2225// Test Type Legalization2226//===----------------------------------------------------------------------===//2227 2228def TestRegionBuilderOp : TEST_Op<"region_builder">;2229def TestReturnOp : TEST_Op<"return", [Pure, ReturnLike, Terminator]> {2230  let arguments = (ins Variadic<AnyType>);2231  let builders = [OpBuilder<(ins),2232    [{ build($_builder, $_state, {}); }]>2233  ];2234}2235def TestCastOp : TEST_Op<"cast">,2236  Arguments<(ins Variadic<AnyType>)>, Results<(outs AnyType)>;2237def TestInvalidOp : TEST_Op<"invalid", [Terminator]>,2238  Arguments<(ins Variadic<AnyType>)>;2239def TestTypeProducerOp : TEST_Op<"type_producer">,2240  Results<(outs AnyType)>;2241def TestValidProducerOp : TEST_Op<"valid_producer">,2242  Results<(outs AnyType)>;2243def TestValidConsumerOp : TEST_Op<"valid_consumer">,2244  Arguments<(ins AnyType)>;2245def TestAnotherTypeProducerOp : TEST_Op<"another_type_producer">,2246  Results<(outs AnyType)>;2247def TestTypeConsumerOp : TEST_Op<"type_consumer">,2248  Arguments<(ins AnyType)>;2249def TestTypeChangerOp : TEST_Op<"type_changer">,2250  Arguments<(ins AnyType)>, Results<(outs AnyType)>;2251def TestValidOp : TEST_Op<"valid", [Terminator]>,2252  Arguments<(ins Variadic<AnyType>)>;2253 2254def TestMergeBlocksOp : TEST_Op<"merge_blocks"> {2255  let summary = "merge_blocks operation";2256  let description = [{2257    Test op with multiple blocks that are merged with Dialect Conversion2258  }];2259 2260  let regions = (region AnyRegion:$body);2261  let results = (outs Variadic<AnyType>:$result);2262}2263 2264def TestRemappedValueRegionOp : TEST_Op<"remapped_value_region",2265                                        [SingleBlock]> {2266  let summary = "remapped_value_region operation";2267  let description = [{2268    Test op that remaps values that haven't yet been converted in Dialect2269    Conversion.2270  }];2271 2272  let regions = (region SizedRegion<1>:$body);2273  let results = (outs Variadic<AnyType>:$result);2274}2275 2276def TestSignatureConversionUndoOp : TEST_Op<"signature_conversion_undo"> {2277  let regions = (region AnyRegion);2278}2279 2280def TestSignatureConversionNoConverterOp2281  : TEST_Op<"signature_conversion_no_converter"> {2282  let regions = (region AnyRegion);2283}2284 2285//===----------------------------------------------------------------------===//2286// Test parser.2287//===----------------------------------------------------------------------===//2288 2289def ParseIntegerLiteralOp : TEST_Op<"parse_integer_literal"> {2290  let results = (outs Variadic<Index>:$results);2291  let hasCustomAssemblyFormat = 1;2292}2293 2294def ParseWrappedKeywordOp : TEST_Op<"parse_wrapped_keyword"> {2295  let arguments = (ins StrAttr:$keyword);2296  let hasCustomAssemblyFormat = 1;2297}2298 2299def ParseB64BytesOp : TEST_Op<"parse_b64"> {2300  let arguments = (ins StrAttr:$b64);2301  let hasCustomAssemblyFormat = 1;2302}2303 2304//===----------------------------------------------------------------------===//2305// Test region argument list parsing.2306//===----------------------------------------------------------------------===//2307 2308def IsolatedRegionOp : TEST_Op<"isolated_region", [IsolatedFromAbove]> {2309  let summary =  "isolated region operation";2310  let description = [{2311    Test op with an isolated region, to test passthrough region arguments. Each2312    argument is of index type.2313  }];2314 2315  let arguments = (ins Index);2316  let regions = (region SizedRegion<1>:$region);2317  let hasCustomAssemblyFormat = 1;2318}2319 2320def SSACFGRegionOp : TEST_Op<"ssacfg_region",  [2321    DeclareOpInterfaceMethods<RegionKindInterface>]> {2322  let summary =  "operation with an SSACFG region";2323  let description = [{2324    Test op that defines an SSACFG region.2325  }];2326 2327  let regions = (region VariadicRegion<AnyRegion>:$regions);2328  let arguments = (ins Variadic<AnyType>);2329  let results = (outs Variadic<AnyType>);2330}2331 2332def GraphRegionOp : TEST_Op<"graph_region",  [2333    DeclareOpInterfaceMethods<RegionKindInterface>]> {2334  let summary =  "operation with a graph region";2335  let description = [{2336    Test op that defines a graph region.2337  }];2338 2339  let regions = (region AnyRegion:$region);2340  let assemblyFormat = "attr-dict-with-keyword $region";2341}2342 2343def IsolatedGraphRegionOp : TEST_Op<"isolated_graph_region",  [2344    DeclareOpInterfaceMethods<RegionKindInterface>,2345    IsolatedFromAbove]> {2346  let summary =  "isolated from above operation with a graph region";2347  let description = [{2348    Test op that defines a graph region which is isolated from above.2349  }];2350 2351  let regions = (region AnyRegion:$region);2352  let assemblyFormat = "attr-dict-with-keyword $region";2353}2354 2355def AffineScopeOp : TEST_Op<"affine_scope", [AffineScope]> {2356  let summary =  "affine scope operation";2357  let description = [{2358    Test op that defines a new affine scope.2359  }];2360 2361  let regions = (region SizedRegion<1>:$region);2362  let hasCustomAssemblyFormat = 1;2363}2364 2365//===----------------------------------------------------------------------===//2366// Custom printer/parser2367//===----------------------------------------------------------------------===//2368 2369def CustomDimensionListAttrOp : TEST_Op<"custom_dimension_list_attr"> {2370  let description = [{2371    Test printing/parsing of dimension list attribute.2372  }];2373  let arguments = (ins DenseI64ArrayAttr:$dimension_list);2374  let assemblyFormat = [{2375    `dimension_list` `=` custom<DimensionList>($dimension_list)2376    attr-dict2377  }];2378}2379 2380def OptionalCustomAttrOp : TEST_Op<"optional_custom_attr"> {2381  let description = [{2382    Test using a custom directive as the optional group anchor and the first2383    element to parse. It is expected to return an `OptionalParseResult`.2384  }];2385  let arguments = (ins OptionalAttr<I1Attr>:$attr);2386  let assemblyFormat = [{2387    attr-dict (custom<OptionalCustomParser>($attr)^) : (`bar`)?2388  }];2389}2390 2391//===----------------------------------------------------------------------===//2392// Test OpAsmInterface.2393//===----------------------------------------------------------------------===//2394 2395def AsmInterfaceOp : TEST_Op<"asm_interface_op"> {2396  let results = (outs AnyType:$first, Variadic<AnyType>:$middle_results,2397                      AnyType);2398}2399 2400def AsmDialectInterfaceOp : TEST_Op<"asm_dialect_interface_op"> {2401  let results = (outs AnyType);2402}2403 2404//===----------------------------------------------------------------------===//2405// Test ArrayOfAttr2406//===----------------------------------------------------------------------===//2407 2408// Embed the array attributes directly in the assembly format for a nice syntax.2409def ArrayOfAttrOp : TEST_Op<"array_of_attr_op"> {2410  let arguments = (ins TestArrayOfUglyAttrs:$a, TestArrayOfInts:$b,2411                       TestArrayOfEnums:$c);2412  let assemblyFormat = "`a` `=` $a `,` `b` `=` $b `,` `c` `=` $c attr-dict";2413}2414 2415//===----------------------------------------------------------------------===//2416// Test SideEffects2417//===----------------------------------------------------------------------===//2418 2419def SideEffectOp : TEST_Op<"side_effect_op",2420    [DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,2421     DeclareOpInterfaceMethods<TestEffectOpInterface>]> {2422  let results = (outs AnyType:$result);2423}2424 2425def SideEffectWithRegionOp : TEST_Op<"side_effect_with_region_op",2426    [DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,2427     DeclareOpInterfaceMethods<TestEffectOpInterface>]> {2428  let arguments = (ins AnyType:$operand);2429  let results = (outs AnyType:$result);2430  let regions = (region AnyRegion:$region);2431  let assemblyFormat = [{2432    `(` $operand`)` $region attr-dict `:`  type($operand)  `->` type($result)2433  }];2434}2435 2436//===----------------------------------------------------------------------===//2437// Copy Operation Test2438//===----------------------------------------------------------------------===//2439 2440def CopyOp : TEST_Op<"copy", []> {2441  let description = [{2442    Represents a copy operation.2443  }];2444  let arguments = (ins Res<AnyRankedOrUnrankedMemRef, "", [MemRead]>:$source,2445                   Res<AnyRankedOrUnrankedMemRef, "", [MemWrite]>:$target);2446  let assemblyFormat = [{2447    `(` $source `,` $target `)` `:` `(` type($source) `,` type($target) `)`2448     attr-dict2449  }];2450}2451 2452//===----------------------------------------------------------------------===//2453// Test Buffer/Tensor2454//===----------------------------------------------------------------------===//2455 2456def RegionYieldOp : TEST_Op<"region_yield",2457      [Pure, ReturnLike, Terminator]> {2458  let description = [{2459    This operation is used in a region and yields the corresponding type for2460    that operation.2461  }];2462  let arguments = (ins AnyType:$result);2463  let assemblyFormat = [{2464    $result `:` type($result) attr-dict2465  }];2466  let builders = [OpBuilder<(ins),2467    [{ build($_builder, $_state, {}); }]>2468  ];2469}2470 2471class BufferBasedOpBase<string mnemonic, list<Trait> traits>2472    : TEST_Op<mnemonic, traits> {2473  let description = [{2474    A buffer based operation, that uses memRefs as input and output.2475  }];2476  let arguments = (ins Arg<AnyRankedOrUnrankedMemRef, "reading",2477                           [MemRead]>:$input,2478                       Arg<AnyRankedOrUnrankedMemRef, "writing",2479                           [MemWrite]>:$output);2480}2481 2482def BufferBasedOp : BufferBasedOpBase<"buffer_based", []>{2483  let assemblyFormat = [{2484    `in` `(` $input`:` type($input) `)` `out` `(` $output`:` type($output) `)`2485    attr-dict2486  }];2487}2488 2489def RegionBufferBasedOp : BufferBasedOpBase<"region_buffer_based",2490      [SingleBlockImplicitTerminator<"RegionYieldOp">]> {2491  let regions = (region AnyRegion:$region);2492  let assemblyFormat = [{2493    `in` `(` $input`:` type($input) `)` `out` `(` $output`:` type($output) `)`2494    $region attr-dict2495  }];2496}2497 2498def TensorBasedOp : TEST_Op<"tensor_based", []> {2499  let description = [{2500    A tensor based operation, that uses a tensor as an input and results in a2501    tensor again.2502  }];2503  let arguments = (ins AnyRankedTensor:$input);2504  let results = (outs AnyRankedTensor:$result);2505  let assemblyFormat = [{2506    `in` `(` $input`:` type($input) `)` `->` type($result) attr-dict2507  }];2508}2509 2510def ReadBufferOp : TEST_Op<"read_buffer", [DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {2511  let description = [{2512    An operation that reads the buffer operand and dumps its contents.2513  }];2514  let arguments = (ins AnyRankedOrUnrankedMemRef:$buffer);2515}2516 2517def ForwardBufferOp : TEST_Op<"forward_buffer", [Pure]> {2518  let description = [{2519    A pure operation that takes a buffer and returns a buffer. This op does not2520    have any side effects, so it cannot allocate or read a buffer from memory.2521    It must return the input buffer (or a view thereof). This op purposely does2522    does not implement any interface.2523  }];2524  let arguments = (ins AnyRankedOrUnrankedMemRef:$buffer);2525  let results = (outs AnyRankedOrUnrankedMemRef:$result);2526}2527 2528//===----------------------------------------------------------------------===//2529// Test ValueBoundsOpInterface2530//===----------------------------------------------------------------------===//2531 2532def TestValueWithBoundsOp : TEST_Op<"value_with_bounds", [2533    DeclareOpInterfaceMethods<ValueBoundsOpInterface, ["populateBoundsForIndexValue"]>2534  ]> {2535  let description = [{2536    Creates a value with specified [min, max] range for value bounds analysis.2537 2538    Example:2539 2540    ```mlir2541    %0 = test.value_with_bounds { min = 4 : index, max = 5 : index}2542    ```2543  }];2544  let arguments = (ins IndexAttr:$min, IndexAttr:$max);2545  let results = (outs Index:$result);2546  let assemblyFormat = "attr-dict";2547}2548 2549 2550def ReifyBoundOp : TEST_Op<"reify_bound", [Pure]> {2551  let description = [{2552    Reify a bound for the given index-typed value or dimension size of a shaped2553    value. "LB", "EQ" and "UB" bounds are supported. If `scalable` is set,2554    `vscale_min` and `vscale_max` must be provided, which allows computing2555    a bound in terms of "vector.vscale" for a given range of vscale.2556  }];2557 2558  let arguments = (ins AnyType:$var,2559                       OptionalAttr<I64Attr>:$dim,2560                       DefaultValuedAttr<StrAttr, "\"EQ\"">:$type,2561                       UnitAttr:$constant,2562                       UnitAttr:$scalable,2563                       OptionalAttr<I64Attr>:$vscale_min,2564                       OptionalAttr<I64Attr>:$vscale_max);2565  let results = (outs Index:$result);2566 2567  let extraClassDeclaration = [{2568    ::mlir::presburger::BoundType getBoundType();2569    ::mlir::ValueBoundsConstraintSet::Variable getVariable();2570  }];2571 2572  let hasVerifier = 1;2573}2574 2575def CompareOp : TEST_Op<"compare"> {2576  let description = [{2577    Compare `lhs` and `rhs`. A remark is emitted which indicates whether the2578    specified comparison operator was proven to hold. The remark also indicates2579    whether the opposite comparison operator was proven to hold.2580 2581    `var_operands` must have exactly two operands: one for the LHS operand and2582    one for the RHS operand. If `lhs_map` is specified, as many operands as2583    `lhs_map` has inputs are expected instead of the first operand. If `rhs_map`2584    is specified, as many operands as `rhs_map` has inputs are expected instead2585    of the second operand.2586  }];2587 2588  let arguments = (ins Variadic<Index>:$var_operands,2589                       DefaultValuedAttr<StrAttr, "\"EQ\"">:$cmp,2590                       OptionalAttr<AffineMapAttr>:$lhs_map,2591                       OptionalAttr<AffineMapAttr>:$rhs_map,2592                       UnitAttr:$compose);2593  let results = (outs);2594 2595  let extraClassDeclaration = [{2596    ::mlir::ValueBoundsConstraintSet::ComparisonOperator2597        getComparisonOperator();2598    ::mlir::ValueBoundsConstraintSet::Variable getLhs();2599    ::mlir::ValueBoundsConstraintSet::Variable getRhs();2600  }];2601 2602  let hasVerifier = 1;2603}2604 2605//===----------------------------------------------------------------------===//2606// Test RegionBranchOpInterface2607//===----------------------------------------------------------------------===//2608 2609def RegionIfYieldOp : TEST_Op<"region_if_yield",2610      [NoMemoryEffect, ReturnLike, Terminator]> {2611  let arguments = (ins Variadic<AnyType>:$results);2612  let assemblyFormat = [{2613    $results `:` type($results) attr-dict2614  }];2615}2616 2617def RegionIfOp : TEST_Op<"region_if",2618      [DeclareOpInterfaceMethods<RegionBranchOpInterface,2619                                 ["getRegionInvocationBounds",2620                                  "getEntrySuccessorOperands"]>,2621       SingleBlockImplicitTerminator<"RegionIfYieldOp">,2622       RecursiveMemoryEffects]> {2623  let description =[{2624    Represents an abstract if-then-else-join pattern. In this context, the then2625    and else regions jump to the join region, which finally returns to its2626    parent op.2627  }];2628 2629  let arguments = (ins Variadic<AnyType>);2630  let results = (outs Variadic<AnyType>:$results);2631  let regions = (region SizedRegion<1>:$thenRegion,2632                        AnyRegion:$elseRegion,2633                        AnyRegion:$joinRegion);2634  let extraClassDeclaration = [{2635    ::mlir::Block::BlockArgListType getThenArgs() {2636      return getBody(0)->getArguments();2637    }2638    ::mlir::Block::BlockArgListType getElseArgs() {2639      return getBody(1)->getArguments();2640    }2641    ::mlir::Block::BlockArgListType getJoinArgs() {2642      return getBody(2)->getArguments();2643    }2644  }];2645  let hasCustomAssemblyFormat = 1;2646}2647 2648def AnyCondOp : TEST_Op<"any_cond",2649      [DeclareOpInterfaceMethods<RegionBranchOpInterface,2650                                 ["getRegionInvocationBounds"]>,2651       RecursiveMemoryEffects]> {2652  let results = (outs Variadic<AnyType>:$results);2653  let regions = (region AnyRegion:$region);2654}2655 2656def LoopBlockOp : TEST_Op<"loop_block",2657    [DeclareOpInterfaceMethods<RegionBranchOpInterface,2658        ["getEntrySuccessorOperands"]>, RecursiveMemoryEffects]> {2659 2660  let results = (outs F32:$floatResult);2661  let arguments = (ins I32:$init);2662  let regions = (region SizedRegion<1>:$body);2663 2664  let assemblyFormat = [{2665    $init `:` functional-type($init, $floatResult) $body2666    attr-dict-with-keyword2667  }];2668}2669 2670def LoopBlockTerminatorOp : TEST_Op<"loop_block_term",2671    [DeclareOpInterfaceMethods<RegionBranchTerminatorOpInterface>, Pure,2672     Terminator]> {2673  let arguments = (ins I32:$nextIterArg, F32:$exitArg);2674 2675  let assemblyFormat = [{2676    `iter` $nextIterArg `exit` $exitArg attr-dict2677  }];2678}2679 2680def TestNoTerminatorOp : TEST_Op<"switch_with_no_break", [2681    NoTerminator,2682    DeclareOpInterfaceMethods<RegionBranchOpInterface>2683  ]> {2684  let arguments = (ins Index:$arg, DenseI64ArrayAttr:$cases);2685  let regions = (region VariadicRegion<SizedRegion<1>>:$caseRegions);2686 2687  let assemblyFormat = [{2688    $arg attr-dict custom<SwitchCases>($cases, $caseRegions)2689  }];2690}2691 2692//===----------------------------------------------------------------------===//2693// Test TableGen generated build() methods2694//===----------------------------------------------------------------------===//2695 2696def TableGenConstant : TEST_Op<"tblgen_constant"> {2697  let results = (outs AnyType);2698}2699 2700// No variadic args or results.2701def TableGenBuildOp0 : TEST_Op<"tblgen_build_0"> {2702  let arguments = (ins AnyType:$value);2703  let results = (outs AnyType:$result);2704}2705 2706// Sigle variadic arg and single variadic results.2707def TableGenBuildOp1 : TEST_Op<"tblgen_build_1"> {2708  let arguments = (ins Variadic<AnyType>:$inputs);2709  let results = (outs Variadic<AnyType>:$results);2710}2711 2712// Single variadic arg and non-variadic results.2713def TableGenBuildOp2 : TEST_Op<"tblgen_build_2"> {2714  let arguments = (ins Variadic<AnyType>:$inputs);2715  let results = (outs AnyType:$result);2716}2717 2718// Single variadic arg and multiple variadic results.2719def TableGenBuildOp3 : TEST_Op<"tblgen_build_3", [SameVariadicResultSize]> {2720  let arguments = (ins Variadic<AnyType>:$inputs);2721  let results = (outs Variadic<AnyType>:$resultA, Variadic<AnyType>:$resultB);2722}2723 2724// Single variadic arg, non variadic results, with SameOperandsAndResultType.2725// Tests suppression of ambiguous build methods for operations with2726// SameOperandsAndResultType trait.2727def TableGenBuildOp4 : TEST_Op<"tblgen_build_4", [SameOperandsAndResultType]> {2728  let arguments = (ins Variadic<AnyType>:$inputs);2729  let results = (outs AnyType:$result);2730}2731 2732// Base class for testing `build` methods for ops with2733// InferReturnTypeOpInterface.2734class TableGenBuildInferReturnTypeBaseOp<string mnemonic,2735                                         list<Trait> traits = []>2736    : TEST_Op<mnemonic, [InferTypeOpInterface] # traits> {2737  let arguments = (ins Variadic<AnyType>:$inputs);2738  let results = (outs AnyType:$result);2739 2740  let extraClassDeclaration = [{2741    static ::llvm::LogicalResult inferReturnTypes(::mlir::MLIRContext *,2742          ::std::optional<::mlir::Location> location, ::mlir::ValueRange operands,2743          ::mlir::DictionaryAttr attributes, mlir::OpaqueProperties properties, ::mlir::RegionRange regions,2744          ::llvm::SmallVectorImpl<::mlir::Type> &inferredReturnTypes) {2745      inferredReturnTypes.assign({operands[0].getType()});2746      return ::mlir::success();2747    }2748   }];2749}2750 2751// Op with InferTypeOpInterface and regions.2752def TableGenBuildOp5 : TableGenBuildInferReturnTypeBaseOp<2753    "tblgen_build_5", [InferTypeOpInterface]> {2754  let regions = (region AnyRegion:$body);2755}2756 2757// Two variadic args, non variadic results, with AttrSizedOperandSegments2758// Test build method generation for property conversion & type inference.2759def TableGenBuildOp6 : TEST_Op<"tblgen_build_6", [AttrSizedOperandSegments]> {2760  let arguments = (ins Variadic<AnyType>:$a, Variadic<AnyType>:$b);2761  let results = (outs F32:$result);2762}2763 2764// An inherent attribute. Test collective builders, both those that take properties as2765// properties structs and those that take an attribute dictionary.2766def TableGenBuildOp7 : TEST_Op<"tblgen_build_7", []> {2767  let arguments = (ins BoolAttr:$attr0);2768  let results = (outs);2769}2770 2771//===----------------------------------------------------------------------===//2772// Test BufferPlacement2773//===----------------------------------------------------------------------===//2774 2775def GetTupleElementOp: TEST_Op<"get_tuple_element"> {2776  let description = [{2777    Test op that returns a specified element of the tuple.2778  }];2779 2780  let arguments = (ins2781    TupleOf<[AnyType]>,2782    I32Attr:$index2783  );2784  let results = (outs AnyType);2785}2786 2787def MakeTupleOp: TEST_Op<"make_tuple"> {2788  let description = [{2789    Test op that creates a tuple value from a list of values.2790  }];2791 2792  let arguments = (ins2793    Variadic<AnyType>:$inputs2794  );2795  let results = (outs TupleOf<[AnyType]>);2796}2797 2798//===----------------------------------------------------------------------===//2799// Test Target DataLayout2800//===----------------------------------------------------------------------===//2801 2802def OpWithDataLayoutOp : TEST_Op<"op_with_data_layout",2803                                 [IsolatedFromAbove, HasDefaultDLTIDataLayout, DataLayoutOpInterface]> {2804  let summary =2805      "An op that uses DataLayout implementation from the Target dialect";2806  let regions = (region VariadicRegion<AnyRegion>:$regions);2807}2808 2809def DataLayoutQueryOp : TEST_Op<"data_layout_query"> {2810  let summary = "A token op recognized by data layout query test pass";2811  let description = [{2812    The data layout query pass pattern-matches this op and attaches to it an2813    array attribute containing the result of data layout query of the result2814    type of this op.2815  }];2816 2817  let results = (outs AnyType:$res);2818}2819 2820//===----------------------------------------------------------------------===//2821// Test Reducer Patterns2822//===----------------------------------------------------------------------===//2823 2824def OpCrashLong : TEST_Op<"op_crash_long"> {2825  let arguments = (ins I32, I32, I32);2826  let results = (outs I32);2827}2828 2829def OpCrashShort : TEST_Op<"op_crash_short"> {2830  let results = (outs I32);2831}2832 2833def : Pat<(OpCrashLong $_, $_, $_), (OpCrashShort)>;2834 2835//===----------------------------------------------------------------------===//2836// Test DestinationStyleOpInterface.2837//===----------------------------------------------------------------------===//2838 2839def TestDestinationStyleOp :2840    TEST_Op<"destination_style_op", [2841      DestinationStyleOpInterface,2842      AttrSizedOperandSegments]> {2843  let arguments = (ins2844    Variadic<AnyType>:$inputs,2845    Variadic<AnyType>:$outputs,2846    Variadic<AnyType>:$other_operands);2847  let results = (outs Variadic<AnyType>:$results);2848  let assemblyFormat = [{2849    attr-dict (`ins` `(` $inputs^ `:` type($inputs) `)`)?2850    (`outs` `(` $outputs^  `:` type($outputs) `)`)?2851    (`(` $other_operands^ `:` type($other_operands) `)`)?2852    (`->` type($results)^)?2853  }];2854 2855  let extraClassDeclaration = [{2856    mlir::MutableOperandRange getDpsInitsMutable() {2857      return getOutputsMutable();2858    }2859  }];2860}2861 2862//===----------------------------------------------------------------------===//2863// Test LinalgConvolutionOpInterface.2864//===----------------------------------------------------------------------===//2865 2866def TestLinalgConvOpNotLinalgOp : TEST_Op<"conv_op_not_linalg_op", [2867    LinalgConvolutionOpInterface]> {2868  let arguments = (ins2869    AnyType:$image, AnyType:$filter, AnyType:$output);2870  let results = (outs AnyRankedTensor:$result);2871}2872 2873def TestLinalgConvOp :2874  TEST_Op<"linalg_conv_op", [AttrSizedOperandSegments, SingleBlock,2875      DestinationStyleOpInterface, LinalgStructuredInterface,2876      LinalgConvolutionOpInterface]> {2877 2878  let arguments = (ins Variadic<AnyType>:$inputs,2879    Variadic<AnyType>:$outputs);2880  let results = (outs Variadic<AnyType>:$results);2881  let regions = (region AnyRegion:$region);2882 2883  let assemblyFormat = [{2884    attr-dict (`ins` `(` $inputs^ `:` type($inputs) `)`)?2885    `outs` `(` $outputs `:` type($outputs) `)`2886    $region (`->` type($results)^)?2887  }];2888 2889  let extraClassDeclaration = [{2890    bool hasIndexSemantics() { return false; }2891 2892    static void regionBuilder(mlir::ImplicitLocOpBuilder &b, mlir::Block &block,2893                              mlir::ArrayRef<mlir::NamedAttribute> attrs,2894                              llvm::function_ref<mlir::InFlightDiagnostic()> emitError) {2895      mlir::linalg::YieldOp::create(b,block.getArguments().back());2896    }2897 2898    static std::function<void(mlir::ImplicitLocOpBuilder &, mlir::Block &,2899                              mlir::ArrayRef<mlir::NamedAttribute>,2900                              llvm::function_ref<mlir::InFlightDiagnostic()>)>2901    getRegionBuilder() {2902      return &regionBuilder;2903    }2904 2905    llvm::SmallVector<mlir::utils::IteratorType> getIteratorTypesArray() {2906      auto attrs = getOperation()->getAttrOfType<mlir::ArrayAttr>("iterator_types");2907      auto range = attrs.getAsValueRange<IteratorTypeAttr, mlir::utils::IteratorType>();2908      return {range.begin(), range.end()};2909    }2910 2911    mlir::ArrayAttr getIndexingMaps() {2912      return getOperation()->getAttrOfType<mlir::ArrayAttr>("indexing_maps");2913    }2914 2915    std::string getLibraryCallName() {2916      return "";2917    }2918 2919    mlir::MutableOperandRange getDpsInitsMutable() {2920      return getOutputsMutable();2921    }2922  }];2923}2924 2925//===----------------------------------------------------------------------===//2926// Test LinalgFillOpInterface.2927//===----------------------------------------------------------------------===//2928 2929def TestLinalgFillOpNotLinalgOp : TEST_Op<"fill_op_not_linalg_op", [2930    LinalgFillOpInterface]> {2931  let arguments = (ins2932    AnyType:$value, AnyType:$output);2933  let results = (outs AnyRankedTensor:$result);2934}2935 2936def TestLinalgFillOp :2937  TEST_Op<"linalg_fill_op", [AttrSizedOperandSegments, SingleBlock,2938      DestinationStyleOpInterface, LinalgStructuredInterface,2939      LinalgFillOpInterface]> {2940 2941  let arguments = (ins Variadic<AnyType>:$inputs,2942    Variadic<AnyType>:$outputs);2943  let results = (outs Variadic<AnyType>:$results);2944  let regions = (region AnyRegion:$region);2945 2946  let assemblyFormat = [{2947    attr-dict (`ins` `(` $inputs^ `:` type($inputs) `)`)?2948    `outs` `(` $outputs `:` type($outputs) `)`2949    $region (`->` type($results)^)?2950  }];2951 2952  let extraClassDeclaration = [{2953    bool hasIndexSemantics() { return false; }2954 2955    static void regionBuilder(mlir::ImplicitLocOpBuilder &b, mlir::Block &block,2956                              mlir::ArrayRef<mlir::NamedAttribute> attrs,2957                              llvm::function_ref<mlir::InFlightDiagnostic()> emitError) {2958      mlir::linalg::YieldOp::create(b,block.getArguments().back());2959    }2960 2961    static std::function<void(mlir::ImplicitLocOpBuilder &, mlir::Block &,2962                              mlir::ArrayRef<mlir::NamedAttribute>,2963                              llvm::function_ref<mlir::InFlightDiagnostic()>)>2964    getRegionBuilder() {2965      return &regionBuilder;2966    }2967 2968    llvm::SmallVector<mlir::utils::IteratorType> getIteratorTypesArray() {2969      auto attrs = getOperation()->getAttrOfType<mlir::ArrayAttr>("iterator_types");2970      auto range = attrs.getAsValueRange<IteratorTypeAttr, mlir::utils::IteratorType>();2971      return {range.begin(), range.end()};2972    }2973 2974    mlir::ArrayAttr getIndexingMaps() {2975      return getOperation()->getAttrOfType<mlir::ArrayAttr>("indexing_maps");2976    }2977 2978    std::string getLibraryCallName() {2979      return "";2980    }2981 2982    mlir::MutableOperandRange getDpsInitsMutable() {2983      return getOutputsMutable();2984    }2985  }];2986}2987 2988//===----------------------------------------------------------------------===//2989// Test TilingInterface.2990//===----------------------------------------------------------------------===//2991 2992def Test_TilingNoDpsOp : TEST_Op<"tiling_no_dps_op",2993    [Pure, DeclareOpInterfaceMethods<TilingInterface,2994      ["getIterationDomain",2995       "getLoopIteratorTypes",2996       "getResultTilePosition",2997       "getTiledImplementation"]>]> {2998  let arguments = (ins AnyRankedTensor:$lhs, AnyRankedTensor:$rhs);2999  let results = (outs AnyRankedTensor:$result);3000}3001 3002//===----------------------------------------------------------------------===//3003// Test NVVM RequiresSM trait.3004//===----------------------------------------------------------------------===//3005 3006def TestNVVMRequiresSMOp :3007    TEST_Op<"nvvm_requires_sm_80", [NVVMRequiresSM<80>]> {3008  let arguments = (ins );3009  let assemblyFormat = "attr-dict";3010}3011 3012def TestNVVMRequiresSMArchCondOp :3013    TEST_Op<"nvvm_requires_sm_90a", [NVVMRequiresSMa<[90]>]> {3014  let arguments = (ins );3015  let assemblyFormat = "attr-dict";3016}3017 3018def TestNVVMRequirestSMArchCondMultiOp :3019    TEST_Op<"nvvm_requires_sm_90a_or_sm_100a", [NVVMRequiresSMa<[90, 100]>]> {3020  let arguments = (ins );3021  let assemblyFormat = "attr-dict";3022}3023 3024//===----------------------------------------------------------------------===//3025// Test Ops with Default-Valued String Attributes3026//===----------------------------------------------------------------------===//3027 3028def TestDefaultStrAttrNoValueOp : TEST_Op<"no_str_value"> {3029  let arguments = (ins DefaultValuedAttr<StrAttr, "">:$value);3030  let assemblyFormat = "attr-dict";3031}3032 3033def TestDefaultStrAttrHasValueOp : TEST_Op<"has_str_value"> {3034  let arguments = (ins DefaultValuedStrAttr<StrAttr, "">:$value);3035  let assemblyFormat = "attr-dict";3036}3037 3038def : Pat<(TestDefaultStrAttrNoValueOp $value),3039          (TestDefaultStrAttrHasValueOp ConstantStrAttr<StrAttr, "foo">)>;3040 3041//===----------------------------------------------------------------------===//3042// Test Ops with variadics3043//===----------------------------------------------------------------------===//3044 3045def TestVariadicRewriteSrcOp : TEST_Op<"variadic_rewrite_src_op", [AttrSizedOperandSegments]> {3046  let arguments = (ins3047    Variadic<AnyType>:$arg,3048    AnyType:$brg,3049    Variadic<AnyType>:$crg3050  );3051}3052 3053def TestVariadicRewriteDstOp : TEST_Op<"variadic_rewrite_dst_op", [AttrSizedOperandSegments]> {3054  let arguments = (ins3055    AnyType:$brg,3056    Variadic<AnyType>:$crg,3057    Variadic<AnyType>:$arg3058  );3059}3060 3061def : Pat<(TestVariadicRewriteSrcOp $arg, $brg, $crg),3062          (TestVariadicRewriteDstOp $brg, $crg, $arg)>;3063 3064//===----------------------------------------------------------------------===//3065// Test Ops with Default-Valued Attributes and Differing Print Settings3066//===----------------------------------------------------------------------===//3067 3068def TestDefaultAttrPrintOp : TEST_Op<"default_value_print"> {3069  let arguments = (ins DefaultValuedAttr<I32Attr, "0">:$value_with_default,3070                   I32:$operand);3071  let assemblyFormat = "attr-dict $operand";3072}3073 3074//===----------------------------------------------------------------------===//3075// Test Ops with effects3076//===----------------------------------------------------------------------===//3077 3078def TestResource : Resource<"TestResource">;3079 3080def TestEffectsOpA : TEST_Op<"op_with_effects_a"> {3081  let arguments = (ins3082    Arg<Variadic<AnyMemRef>, "", [MemRead]>,3083    Arg<FlatSymbolRefAttr, "", [MemRead]>:$first,3084    Arg<SymbolRefAttr, "", [MemWrite]>:$second,3085    Arg<OptionalAttr<SymbolRefAttr>, "", [MemRead]>:$optional_symbol3086  );3087 3088  let results = (outs Res<AnyMemRef, "", [MemAlloc<TestResource, 0>]>);3089}3090 3091def TestEffectsOpB : TEST_Op<"op_with_effects_b",3092    [MemoryEffects<[MemWrite<TestResource, 0>]>]>;3093 3094def TestEffectsRead : TEST_Op<"op_with_memread",3095    [MemoryEffects<[MemRead]>]> {3096  let results = (outs AnyInteger);3097}3098 3099def TestEffectsWrite : TEST_Op<"op_with_memwrite",3100    [MemoryEffects<[MemWrite]>]>;3101 3102def TestEffectsResult : TEST_Op<"test_effects_result"> {3103  let results = (outs Res<I32, "", [MemAlloc, MemWrite]>);3104}3105 3106//===----------------------------------------------------------------------===//3107// Test Ops with verifiers3108//===----------------------------------------------------------------------===//3109 3110def TestVerifiersOp : TEST_Op<"verifiers",3111                              [SingleBlock, NoTerminator, IsolatedFromAbove]> {3112  let arguments = (ins I32:$input);3113  let regions = (region SizedRegion<1>:$region);3114  let hasVerifier = 1;3115  let hasRegionVerifier = 1;3116}3117 3118//===----------------------------------------------------------------------===//3119// Test Loop Op with a graph region3120//===----------------------------------------------------------------------===//3121 3122// Test loop op with a graph region.3123def TestGraphLoopOp : TEST_Op<"graph_loop",3124                         [LoopLikeOpInterface, NoMemoryEffect,3125                          RecursivelySpeculatable, SingleBlock,3126                          RegionKindInterface, HasOnlyGraphRegion]> {3127  let arguments = (ins Variadic<AnyType>:$args);3128  let results = (outs Variadic<AnyType>:$rets);3129  let regions = (region SizedRegion<1>:$body);3130 3131  let assemblyFormat = [{3132    $args $body attr-dict `:` functional-type(operands, results)3133  }];3134 3135  let extraClassDeclaration = [{3136    llvm::SmallVector<mlir::Region *> getLoopRegions() { return {&getBody()}; }3137  }];3138}3139 3140//===----------------------------------------------------------------------===//3141// Test InferIntRangeInterface3142//===----------------------------------------------------------------------===//3143def InferIntRangeType : AnyTypeOf<[AnyInteger, Index, VectorOfNonZeroRankOf<[AnyInteger, Index]>]>;3144 3145def TestWithBoundsOp : TEST_Op<"with_bounds",3146                          [DeclareOpInterfaceMethods<InferIntRangeInterface, ["inferResultRanges"]>,3147                           NoMemoryEffect]> {3148  let description = [{3149    Creates a value with specified [min, max] range for integer range analysis.3150 3151    Example:3152 3153    ```mlir3154    %0 = test.with_bounds { umin = 4 : index, umax = 5 : index, smin = 4 : index, smax = 5 : index } : index3155    ```3156  }];3157 3158  let arguments = (ins APIntAttr:$umin,3159                       APIntAttr:$umax,3160                       APIntAttr:$smin,3161                       APIntAttr:$smax);3162  let results = (outs InferIntRangeType:$fakeVal);3163 3164  let assemblyFormat = "attr-dict `:` type($fakeVal)";3165}3166 3167def TestWithBoundsRegionOp : TEST_Op<"with_bounds_region",3168                          [DeclareOpInterfaceMethods<InferIntRangeInterface, ["inferResultRanges"]>,3169                           SingleBlock, NoTerminator]> {3170  let arguments = (ins APIntAttr:$umin,3171                       APIntAttr:$umax,3172                       APIntAttr:$smin,3173                       APIntAttr:$smax);3174  // The region has one argument of any integer type3175  let regions = (region SizedRegion<1>:$region);3176  let hasCustomAssemblyFormat = 1;3177}3178 3179def TestIncrementOp : TEST_Op<"increment",3180                         [DeclareOpInterfaceMethods<InferIntRangeInterface, ["inferResultRanges"]>,3181                         NoMemoryEffect, AllTypesMatch<["value", "result"]>]> {3182  let arguments = (ins InferIntRangeType:$value);3183  let results = (outs InferIntRangeType:$result);3184 3185  let assemblyFormat = "attr-dict $value `:` type($result)";3186}3187 3188def TestReflectBoundsOp : TEST_Op<"reflect_bounds",3189                         [DeclareOpInterfaceMethods<InferIntRangeInterface, ["inferResultRanges"]>,3190                          AllTypesMatch<["value", "result"]>]> {3191  let description = [{3192    Integer range analysis will update this op to reflect inferred integer range3193    of the input, so it can be checked with FileCheck3194 3195    Example:3196 3197    ```mlir3198    CHECK: test.reflect_bounds {smax = 7 : index, smin = 0 : index, umax = 7 : index, umin = 0 : index}3199    %1 = test.reflect_bounds %0 : index3200    ```3201  }];3202 3203  let arguments = (ins InferIntRangeType:$value,3204                       OptionalAttr<APIntAttr>:$umin,3205                       OptionalAttr<APIntAttr>:$umax,3206                       OptionalAttr<APIntAttr>:$smin,3207                       OptionalAttr<APIntAttr>:$smax);3208  let results = (outs InferIntRangeType:$result);3209 3210  let assemblyFormat = "attr-dict $value `:` type($result)";3211}3212 3213//===----------------------------------------------------------------------===//3214// Test ConditionallySpeculatable3215//===----------------------------------------------------------------------===//3216 3217def ConditionallySpeculatableOp : TEST_Op<"conditionally_speculatable_op",3218    [ConditionallySpeculatable, NoMemoryEffect]> {3219  let description = [{3220    Op used to test conditional speculation.  This op can be speculatively3221    executed if the input to it is an `arith.constant`.3222  }];3223 3224  let arguments = (ins I32:$input);3225  let results = (outs I32:$result);3226 3227  let extraClassDeclaration = [{3228    ::mlir::Speculation::Speculatability getSpeculatability();3229  }];3230 3231  let extraClassDefinition = [{3232    ::mlir::Speculation::Speculatability3233    ConditionallySpeculatableOp::getSpeculatability() {3234      Operation* definingOp = getInput().getDefiningOp();3235      return definingOp && isa<::mlir::arith::ConstantOp>(definingOp) ?3236          ::mlir::Speculation::Speculatable : ::mlir::Speculation::NotSpeculatable;3237    }3238  }];3239}3240 3241def PureOp : TEST_Op<"always_speculatable_op", [Pure]> {3242  let description = [{3243    Op used to test conditional speculation.  This op can always be3244    speculatively executed.3245  }];3246  let results = (outs I32:$result);3247}3248 3249def NeverSpeculatableOp : TEST_Op<"never_speculatable_op", [ConditionallySpeculatable]> {3250  let description = [{3251    Op used to test conditional speculation.  This op can never be3252    speculatively executed.3253  }];3254  let results = (outs I32:$result);3255 3256  let extraClassDeclaration = [{3257    ::mlir::Speculation::Speculatability getSpeculatability() {3258      return ::mlir::Speculation::NotSpeculatable;3259    }3260  }];3261}3262 3263def RecursivelySpeculatableOp : TEST_Op<"recursively_speculatable_op", [3264    RecursivelySpeculatable, RecursiveMemoryEffects]> {3265  let description = [{3266    Op used to test conditional speculation.  This op can be speculatively3267    executed only if all the ops in the attached region can be.3268  }];3269  let results = (outs I32:$result);3270  let regions = (region SizedRegion<1>:$body);3271}3272 3273//===---------------------------------------------------------------------===//3274// Test CSE3275//===---------------------------------------------------------------------===//3276 3277def TestCSEOfSingleBlockOp : TEST_Op<"cse_of_single_block_op",3278    [SingleBlockImplicitTerminator<"RegionYieldOp">, Pure]> {3279  let arguments = (ins Variadic<AnyType>:$inputs);3280  let results = (outs Variadic<AnyType>:$outputs);3281  let regions = (region SizedRegion<1>:$region);3282  let assemblyFormat = [{3283    attr-dict `inputs` `(` $inputs `)`3284    $region `:` type($inputs)  `->` type($outputs)3285  }];3286}3287 3288//===----------------------------------------------------------------------===//3289// Test Ops to upgrade base on the dialect versions3290//===----------------------------------------------------------------------===//3291 3292def TestVersionedOpA : TEST_Op<"versionedA"> {3293  // A previous version of the dialect (let's say 1.*) supported an attribute3294  // named "dimensions":3295  // let arguments = (ins3296  //   AnyI64Attr:$dimensions3297  // );3298 3299  // In the current version (2.0) "dimensions" was renamed to "dims", and a new3300  // boolean attribute "modifier" was added. The previous version of the op3301  // corresponds to "modifier=false". We support loading old IR through3302  // upgrading, see `upgradeFromVersion()` in `TestBytecodeDialectInterface`.3303  let arguments = (ins3304   AnyI64Attr:$dims,3305   BoolAttr:$modifier3306  );3307 3308  // Since we use properties to store attributes, we need a custom encoding3309  // reader/writer to handle versioning.3310  let useCustomPropertiesEncoding = 1;3311}3312 3313def TestVersionedOpB : TEST_Op<"versionedB"> {3314  // A previous version of the dialect (let's say 1.*) we encoded TestAttrParams3315  // with a custom encoding:3316  //3317  //    #test.attr_params<X, Y> -> { varInt: Y, varInt: X }3318  //3319  // In the current version (2.0) the encoding changed and the two parameters of3320  // the attribute are swapped:3321  //3322  //    #test.attr_params<X, Y> -> { varInt: X, varInt: Y }3323  //3324  // We support loading old IR through a custom readAttribute method, see3325  // `readAttribute()` in `TestBytecodeDialectInterface`3326  let arguments = (ins3327    TestAttrParams:$attribute3328  );3329}3330 3331def TestVersionedOpC : TEST_Op<"versionedC"> {3332  let arguments = (ins AnyAttrOf<[TestAttrParams,3333                                  I32ElementsAttr]>:$attribute3334  );3335}3336 3337//===----------------------------------------------------------------------===//3338// Test Properties3339//===----------------------------------------------------------------------===//3340 3341 3342// Op with a properties struct defined inline.3343def TestOpWithProperties : TEST_Op<"with_properties"> {3344  let assemblyFormat = [{3345    `a` `=` $a `,`3346    `b` `=` $b `,`3347    `c` `=` $c `,`3348    `flag` `=` $flag `,`3349    `array` `=` $array `,`3350    `array32` `=` $array32 attr-dict}];3351  let arguments = (ins3352    I64Prop:$a,3353    StrAttr:$b, // Attributes can directly be used here.3354    StringProp:$c,3355    BoolProp:$flag,3356    IntArrayProp<I64Prop>:$array, // Example of an array.3357    IntArrayProp<I32Prop>:$array32 // Example of an array.3358  );3359}3360 3361def TestOpWithPropertiesAndAttr3362  : TEST_Op<"with_properties_and_attr"> {3363  let assemblyFormat = "$lhs prop-dict attr-dict";3364 3365  let arguments = (ins I32Attr:$lhs, IntProp<"int64_t">:$rhs);3366}3367 3368def TestOpWithPropertiesAndInferredType3369  : TEST_Op<"with_properties_and_inferred_type", [3370    DeclareOpInterfaceMethods<InferTypeOpInterface>3371  ]> {3372  let assemblyFormat = "$lhs prop-dict attr-dict";3373 3374  let arguments = (ins I32Attr:$lhs, IntProp<"int64_t">:$rhs, OptionalAttr<UnitAttr>: $packed);3375  let results = (outs AnyType:$result);3376}3377 3378// Demonstrate how to wrap an existing C++ class named MyPropStruct.3379def MyStructProperty : Property<"MyPropStruct"> {3380  let convertToAttribute = "return $_storage.asAttribute($_ctxt);";3381  let convertFromAttribute = "return MyPropStruct::setFromAttr($_storage, $_attr, $_diag);";3382  let hashProperty = "$_storage.hash();";3383}3384 3385def TestOpWithWrappedProperties : TEST_Op<"with_wrapped_properties"> {3386  let assemblyFormat = "prop-dict attr-dict";3387  let arguments = (ins3388    MyStructProperty:$prop3389  );3390}3391 3392// Same as above, but without a custom `hashProperty` field, checking3393// that ADL is correctly working.3394def MyStructProperty2 : Property<"MyPropStruct"> {3395  let convertToAttribute = "return $_storage.asAttribute($_ctxt);";3396  let convertFromAttribute = "return MyPropStruct::setFromAttr($_storage, $_attr, $_diag);";3397}3398 3399def TestOpWithWrappedProperties2 : TEST_Op<"with_wrapped_properties2"> {3400  let assemblyFormat = "prop-dict attr-dict";3401  let arguments = (ins3402    MyStructProperty2:$prop3403  );3404}3405 3406def TestOpWithEmptyProperties : TEST_Op<"empty_properties"> {3407  let assemblyFormat = "prop-dict attr-dict";3408  let arguments = (ins);3409}3410 3411def TestOpUsingPropertyInCustom : TEST_Op<"using_property_in_custom"> {3412  let assemblyFormat = "custom<UsingPropertyInCustom>($prop) attr-dict";3413  let arguments = (ins IntArrayProp<I64Prop>:$prop);3414}3415 3416def TestOpUsingPropertyInCustomAndOther3417  : TEST_Op<"using_property_in_custom_and_other"> {3418  let assemblyFormat = "custom<UsingPropertyInCustom>($prop) prop-dict attr-dict";3419  let arguments = (ins3420    IntArrayProp<I64Prop>:$prop,3421    I64Prop:$other3422  );3423}3424 3425def TestOpWithVariadicSegmentProperties : TEST_Op<"variadic_segment_prop",3426    [AttrSizedOperandSegments, AttrSizedResultSegments]> {3427  let arguments = (ins Variadic<I64>:$a1, Variadic<I64>:$a2);3428  let results = (outs Variadic<I64>:$b1, Variadic<I64>:$b2);3429  let assemblyFormat = [{3430    $a1 `:` $a2 `:` type($b1) `:` type($b2) prop-dict attr-dict `end`3431  }];3432}3433 3434def TestOpUsingPropertyRefInCustom : TEST_Op<"using_property_ref_in_custom"> {3435  let assemblyFormat = "custom<IntProperty>($first) `+` custom<SumProperty>($second, ref($first)) attr-dict";3436  let arguments = (ins IntProp<"int64_t">:$first, IntProp<"int64_t">:$second);3437}3438 3439def IntPropertyWithWorseBytecode : Property<"int64_t"> {3440  let writeToMlirBytecode = writeMlirBytecodeWithConvertToAttribute;3441 3442  let readFromMlirBytecode = readMlirBytecodeUsingConvertFromAttribute;3443}3444 3445def TestOpUsingIntPropertyWithWorseBytecode3446    : TEST_Op<"using_int_property_with_worse_bytecode"> {3447  let arguments = (ins IntPropertyWithWorseBytecode:$value);3448}3449 3450// Op with a properties struct defined out-of-line. The struct has custom3451// printer/parser.3452 3453def PropertiesWithCustomPrint : Property<"PropertiesWithCustomPrint"> {3454  let convertToAttribute = [{3455    return getPropertiesAsAttribute($_ctxt, $_storage);3456  }];3457  let convertFromAttribute = [{3458    return setPropertiesFromAttribute($_storage, $_attr, $_diag);3459  }];3460  let hashProperty = [{3461    computeHash($_storage);3462  }];3463}3464 3465def TestOpWithNiceProperties : TEST_Op<"with_nice_properties"> {3466  let assemblyFormat = "prop-dict attr-dict";3467  let arguments = (ins3468     PropertiesWithCustomPrint:$prop3469  );3470  let extraClassDeclaration = [{3471    void printProperties(::mlir::MLIRContext *ctx, ::mlir::OpAsmPrinter &p,3472                         const Properties &prop,3473                         ::mlir::ArrayRef<::llvm::StringRef> elidedProps);3474    static ::mlir::ParseResult  parseProperties(::mlir::OpAsmParser &parser,3475                                     ::mlir::OperationState &result);3476    static ::llvm::LogicalResult readFromMlirBytecode(3477        ::mlir::DialectBytecodeReader &,3478        test::PropertiesWithCustomPrint &prop);3479    static void writeToMlirBytecode(3480        ::mlir::DialectBytecodeWriter &,3481        const test::PropertiesWithCustomPrint &prop);3482  }];3483  let extraClassDefinition = [{3484    ::llvm::LogicalResult TestOpWithNiceProperties::readFromMlirBytecode(3485        ::mlir::DialectBytecodeReader &reader,3486        test::PropertiesWithCustomPrint &prop) {3487      StringRef label;3488      uint64_t value;3489      if (failed(reader.readString(label)) || failed(reader.readVarInt(value)))3490        return failure();3491      prop.label = std::make_shared<std::string>(label.str());3492      prop.value = value;3493      return success();3494    }3495    void TestOpWithNiceProperties::writeToMlirBytecode(3496        ::mlir::DialectBytecodeWriter &writer,3497        const test::PropertiesWithCustomPrint &prop) {3498      writer.writeOwnedString(*prop.label);3499      writer.writeVarInt(prop.value);3500    }3501    void TestOpWithNiceProperties::printProperties(::mlir::MLIRContext *ctx,3502            ::mlir::OpAsmPrinter &p, const Properties &prop,3503            ::mlir::ArrayRef<::llvm::StringRef> elidedProps) {3504      customPrintProperties(p, prop.prop);3505    }3506    ::mlir::ParseResult TestOpWithNiceProperties::parseProperties(3507        ::mlir::OpAsmParser &parser,3508        ::mlir::OperationState &result) {3509      Properties &prop = result.getOrAddProperties<Properties>();3510      if (customParseProperties(parser, prop.prop))3511        return failure();3512      return success();3513    }3514  }];3515}3516 3517def VersionedProperties : Property<"VersionedProperties"> {3518  let convertToAttribute = [{3519    return getPropertiesAsAttribute($_ctxt, $_storage);3520  }];3521  let convertFromAttribute = [{3522    return setPropertiesFromAttribute($_storage, $_attr, $_diag);3523  }];3524  let hashProperty = [{3525    computeHash($_storage);3526  }];3527}3528 3529def TestOpWithVersionedProperties : TEST_Op<"with_versioned_properties"> {3530  let assemblyFormat = "prop-dict attr-dict";3531  let arguments = (ins3532     VersionedProperties:$prop3533  );3534  let extraClassDeclaration = [{3535    void printProperties(::mlir::MLIRContext *ctx, ::mlir::OpAsmPrinter &p,3536                         const Properties &prop,3537                         ::mlir::ArrayRef<::llvm::StringRef> elidedProps);3538    static ::mlir::ParseResult  parseProperties(::mlir::OpAsmParser &parser,3539                                     ::mlir::OperationState &result);3540    static ::llvm::LogicalResult readFromMlirBytecode(3541        ::mlir::DialectBytecodeReader &,3542        test::VersionedProperties &prop);3543    static void writeToMlirBytecode(3544        ::mlir::DialectBytecodeWriter &,3545        const test::VersionedProperties &prop);3546  }];3547  let extraClassDefinition = [{3548    void TestOpWithVersionedProperties::printProperties(::mlir::MLIRContext *ctx,3549            ::mlir::OpAsmPrinter &p, const Properties &prop,3550            ::mlir::ArrayRef<::llvm::StringRef> elidedProps) {3551      customPrintProperties(p, prop.prop);3552    }3553    ::mlir::ParseResult TestOpWithVersionedProperties::parseProperties(3554        ::mlir::OpAsmParser &parser,3555        ::mlir::OperationState &result) {3556      Properties &prop = result.getOrAddProperties<Properties>();3557      if (customParseProperties(parser, prop.prop))3558        return failure();3559      return success();3560    }3561  }];3562}3563 3564def TestOpWithDefaultValuedProperties : TEST_Op<"with_default_valued_properties"> {3565  let assemblyFormat = [{3566    ($a^) : (`na`)?3567    ($b^)?3568    ($c^)?3569    ($unit^)?3570    attr-dict3571  }];3572  let arguments = (ins DefaultValuedAttr<I32Attr, "0">:$a,3573    DefaultValuedProp<StringProp, "\"\"">:$b,3574    DefaultValuedProp<IntProp<"int32_t">, "-1">:$c,3575    UnitProp:$unit);3576}3577 3578def TestOpWithOptionalProperties : TEST_Op<"with_optional_properties"> {3579  let assemblyFormat = [{3580    (`anAttr` `=` $anAttr^)?3581    (`simple` `=` $simple^)?3582    (`simplei8` `=` $simplei8^)?3583    (`simpleui8` `=` $simpleui8^)?3584    (`nonTrivialStorage` `=` $nonTrivialStorage^)?3585    (`hasDefault` `=` $hasDefault^)?3586    (`nested` `=` $nested^)?3587    (`longSyntax` `=` $longSyntax^)?3588    (`hasUnit` $hasUnit^)?3589    (`maybeUnit` `=` $maybeUnit^)?3590    attr-dict3591  }];3592  let arguments = (ins3593    OptionalAttr<I32Attr>:$anAttr,3594    OptionalProp<I64Prop>:$simple,3595    OptionalProp<IntProp<"int8_t">>:$simplei8,3596    OptionalProp<IntProp<"uint8_t">>:$simpleui8,3597    OptionalProp<StringProp>:$nonTrivialStorage,3598    // Confirm that properties with default values now default to nullopt and have3599    // the long syntax.3600    OptionalProp<DefaultValuedProp<I64Prop, "0">>:$hasDefault,3601    OptionalProp<OptionalProp<I64Prop>>:$nested,3602    OptionalProp<StringProp, 0>:$longSyntax,3603    UnitProp:$hasUnit,3604    OptionalProp<UnitProp>:$maybeUnit);3605}3606 3607def TestOpWithArrayProperties : TEST_Op<"with_array_properties"> {3608  let assemblyFormat = [{3609    `ints` `=` $ints3610    `strings` `=` $strings3611    `nested` `=` $nested3612    `opt` `=` $opt3613    `explicitOptions` `=` $explicitOptions3614    `explicitUnits` `=` $explicitUnits3615    ($hasDefault^ `thats_has_default`)?3616    attr-dict3617  }];3618  let arguments = (ins3619    ArrayProp<I64Prop>:$ints,3620    ArrayProp<StringProp>:$strings,3621    ArrayProp<ArrayProp<I32Prop>>:$nested,3622    OptionalProp<ArrayProp<I32Prop>>:$opt,3623    ArrayProp<OptionalProp<I64Prop>>:$explicitOptions,3624    ArrayProp<UnitProp>:$explicitUnits,3625    DefaultValuedProp<ArrayProp<I64Prop>,3626      "::llvm::ArrayRef<int64_t>{}", "::llvm::SmallVector<int64_t>{}">:$hasDefault3627  );3628}3629 3630def NonNegativeI64Prop : ConfinedProp<I64Prop,3631  CPred<"$_self >= 0">, "non-negative int64_t">;3632 3633class NonEmptyArray<Property p> : ConfinedProp3634    <ArrayProp<p>, Neg<CPred<"$_self.empty()">>,3635    "non-empty array of " # p.summary>;3636 3637def OpWithPropertyPredicates : TEST_Op<"op_with_property_predicates"> {3638  let arguments = (ins3639    NonNegativeI64Prop:$scalar,3640    OptionalProp<NonNegativeI64Prop>:$optional,3641    DefaultValuedProp<NonNegativeI64Prop, "0">:$defaulted,3642    ConfinedProp<NonNegativeI64Prop,3643      CPred<"$_self <= 5">, "between 0 and 5">:$more_constrained,3644    ArrayProp<NonNegativeI64Prop>:$array,3645    NonEmptyArray<I64Prop>:$non_empty_unconstrained,3646    NonEmptyArray<NonNegativeI64Prop>:$non_empty_constrained,3647    // Test applying predicates when the fromStorage() on the optional<> isn't trivial.3648    OptionalProp<NonEmptyArray<NonNegativeI64Prop>>:$non_empty_optional,3649    I64Prop:$unconstrained3650  );3651  let assemblyFormat = "attr-dict prop-dict";3652}3653 3654def TestPropPatternOp1 : TEST_Op<"prop_pattern_op_1"> {3655  let arguments = (ins3656    StringProp:$tag,3657    I64Prop:$val,3658    BoolProp:$cond3659  );3660  let results = (outs I32:$results);3661  let assemblyFormat = "$tag $val $cond attr-dict";3662}3663 3664def TestPropPatternOp2 : TEST_Op<"prop_pattern_op_2"> {3665  let arguments = (ins3666    I32:$input,3667    StringProp:$tag3668  );3669  let assemblyFormat = "$input $tag attr-dict";3670}3671 3672def : Pat<3673  (TestPropPatternOp1 $tag, NonNegativeI64Prop:$val, ConstantProp<BoolProp, "false">),3674  (TestPropPatternOp1 $tag, (NativeCodeCall<"$0 + 1"> $val), ConstantProp<BoolProp, "true">)>;3675 3676def : Pat<3677  (TestPropPatternOp2 (TestPropPatternOp1 $tag1, $val, ConstantProp<BoolProp, "true">),3678    PropConstraint<CPred<"!$_self.empty()">, "non-empty string">:$tag2),3679  (TestPropPatternOp23680    (TestPropPatternOp1 $tag1,3681      (NativeCodeCall<"-($0)"> $val),3682      ConstantProp<BoolProp, "false">),3683    (NativeCodeCall<"$0.str() + \".\" + $1.str()"> $tag1, $tag2))3684>;3685 3686//===----------------------------------------------------------------------===//3687// Test Dataflow3688//===----------------------------------------------------------------------===//3689 3690def TestCallAndStoreOp : TEST_Op<"call_and_store",3691    [DeclareOpInterfaceMethods<CallOpInterface>]> {3692  let arguments = (ins3693    SymbolRefAttr:$callee,3694    Arg<AnyMemRef, "", [MemWrite]>:$address,3695    Variadic<AnyType>:$callee_operands,3696    BoolAttr:$store_before_call,3697    OptionalAttr<DictArrayAttr>:$arg_attrs,3698    OptionalAttr<DictArrayAttr>:$res_attrs3699  );3700  let results = (outs3701    Variadic<AnyType>:$results3702  );3703  let assemblyFormat =3704    "$callee `(` $callee_operands `)` `,` $address attr-dict "3705    "`:` functional-type(operands, results)";3706}3707 3708def TestCallOnDeviceOp : TEST_Op<"call_on_device",3709    [DeclareOpInterfaceMethods<CallOpInterface>]> {3710  let arguments = (ins3711    SymbolRefAttr:$callee,3712    Variadic<AnyType>:$forwarded_operands,3713    AnyType:$non_forwarded_device_operand,3714    OptionalAttr<DictArrayAttr>:$arg_attrs,3715    OptionalAttr<DictArrayAttr>:$res_attrs3716  );3717  let results = (outs3718    Variadic<AnyType>:$results3719  );3720  let assemblyFormat =3721    "$callee `(` $forwarded_operands `)` `,` $non_forwarded_device_operand "3722    "attr-dict `:` functional-type(operands, results)";3723}3724 3725def TestStoreWithARegion : TEST_Op<"store_with_a_region",3726    [DeclareOpInterfaceMethods<RegionBranchOpInterface>,3727     SingleBlock]> {3728  let arguments = (ins3729    Arg<AnyMemRef, "", [MemWrite]>:$address,3730    BoolAttr:$store_before_region3731  );3732  let regions = (region AnyRegion:$body);3733  let assemblyFormat =3734    "$address attr-dict-with-keyword regions `:` type($address)";3735}3736 3737def TestStoreWithALoopRegion : TEST_Op<"store_with_a_loop_region",3738    [DeclareOpInterfaceMethods<RegionBranchOpInterface>,3739     SingleBlock]> {3740  let arguments = (ins3741    Arg<AnyMemRef, "", [MemWrite]>:$address,3742    BoolAttr:$store_before_region3743  );3744  let regions = (region AnyRegion:$body);3745  let assemblyFormat =3746    "$address attr-dict-with-keyword regions `:` type($address)";3747}3748 3749def TestStoreWithARegionTerminator : TEST_Op<"store_with_a_region_terminator",3750    [ReturnLike, Terminator, NoMemoryEffect]> {3751  let assemblyFormat = "attr-dict";3752}3753 3754def TestOpOptionallyImplementingInterface3755    : TEST_Op<"op_optionally_implementing_interface",3756        [TestOptionallyImplementedOpInterface]> {3757  let arguments = (ins BoolAttr:$implementsInterface);3758}3759 3760//===----------------------------------------------------------------------===//3761// Test Mem2Reg & SROA3762//===----------------------------------------------------------------------===//3763 3764def TestMultiSlotAlloca : TEST_Op<"multi_slot_alloca",3765    [DeclareOpInterfaceMethods<PromotableAllocationOpInterface>,3766     DeclareOpInterfaceMethods<DestructurableAllocationOpInterface>]> {3767  let results = (outs Variadic<MemRefOf<[I32]>>:$results);3768  let assemblyFormat = "attr-dict `:` functional-type(operands, results)";3769}3770 3771//===----------------------------------------------------------------------===//3772// Test allocation Ops3773//===----------------------------------------------------------------------===//3774 3775def TestAllocWithMultipleResults : TEST_Op<"alloc_with_multiple_results"> {3776  let results = (outs Index:$index,3777                      Res<AnyMemRef, "", [MemAlloc]>:$memref);3778  let assemblyFormat = [{3779     attr-dict `:` type($index) `,` type($memref)3780  }];3781}3782 3783//===----------------------------------------------------------------------===//3784// Test Ops bufferization3785//===----------------------------------------------------------------------===//3786 3787def TestDummyTensorOp : TEST_Op<"dummy_tensor_op",3788    [DeclareOpInterfaceMethods<BufferizableOpInterface,3789        ["bufferize", "bufferizesToMemoryRead",3790         "bufferizesToMemoryWrite", "getAliasingValues"]>]> {3791  let arguments = (ins3792    Arg<Bufferization_TensorLikeTypeInterface>:$input3793  );3794  let results = (outs3795    Arg<Bufferization_TensorLikeTypeInterface>:$output3796  );3797 3798  let extraClassDefinition = [{3799    bool test::TestDummyTensorOp::bufferizesToMemoryRead(::mlir::OpOperand&,3800        const ::mlir::bufferization::AnalysisState&) {3801      return true;3802    }3803    bool test::TestDummyTensorOp::bufferizesToMemoryWrite(::mlir::OpOperand&,3804        const ::mlir::bufferization::AnalysisState&) {3805      return true;3806    }3807    ::mlir::bufferization::AliasingValueList3808    test::TestDummyTensorOp::getAliasingValues(::mlir::OpOperand&,3809        const ::mlir::bufferization::AnalysisState&) {3810      return {};3811    }3812  }];3813}3814 3815def TestDummyMemrefOp : TEST_Op<"dummy_memref_op", []> {3816  let arguments = (ins3817    Arg<Bufferization_BufferLikeTypeInterface>:$input3818  );3819  let results = (outs3820    Arg<Bufferization_BufferLikeTypeInterface>:$output3821  );3822}3823 3824def TestCreateTensorOp : TEST_Op<"create_tensor_op",3825    [DeclareOpInterfaceMethods<BufferizableOpInterface,3826        ["bufferize", "getBufferType", "bufferizesToMemoryRead",3827         "bufferizesToMemoryWrite", "getAliasingValues",3828         "bufferizesToAllocation"]>]> {3829  let arguments = (ins);3830  let results = (outs Arg<Bufferization_TensorLikeTypeInterface>:$output);3831  let extraClassDefinition = [{3832    bool test::TestCreateTensorOp::bufferizesToMemoryRead(::mlir::OpOperand&,3833        const ::mlir::bufferization::AnalysisState&) {3834      return true;3835    }3836    bool test::TestCreateTensorOp::bufferizesToMemoryWrite(::mlir::OpOperand&,3837        const ::mlir::bufferization::AnalysisState&) {3838      return true;3839    }3840    bool test::TestCreateTensorOp::bufferizesToAllocation(mlir::Value value) {3841      return false;3842    }3843 3844    ::mlir::bufferization::AliasingValueList3845    test::TestCreateTensorOp::getAliasingValues(::mlir::OpOperand&,3846        const ::mlir::bufferization::AnalysisState&) {3847      return {};3848    }3849  }];3850}3851 3852def TestCreateMemrefOp : TEST_Op<"create_memref_op"> {3853  let arguments = (ins);3854  let results = (outs Arg<Bufferization_BufferLikeTypeInterface>:$output);3855}3856 3857//===----------------------------------------------------------------------===//3858// Test assembly format references3859//===----------------------------------------------------------------------===//3860 3861def TestOpWithRegionRef : TEST_Op<"dummy_op_with_region_ref", [NoTerminator]> {3862  let regions = (region AnyRegion:$body);3863  let assemblyFormat = [{3864    $body attr-dict custom<DummyRegionRef>(ref($body))3865  }];3866}3867 3868def TestOpWithSuccessorRef : TEST_Op<"dummy_op_with_successor_ref"> {3869  let successors = (successor AnySuccessor:$successor);3870  let assemblyFormat = [{3871    $successor attr-dict custom<DummySuccessorRef>(ref($successor))3872  }];3873}3874 3875def CallWithSegmentsOp : TEST_Op<"call_with_segments",3876    [AttrSizedOperandSegments,3877  DeclareOpInterfaceMethods<CallOpInterface>]> {3878  let summary = "test call op with segmented args";3879  let arguments = (ins3880    FlatSymbolRefAttr:$callee,3881    Variadic<AnyType>:$prefix,   // non-arg segment (e.g., 'in')3882    Variadic<AnyType>:$args,     // <-- the call *arguments* segment3883    Variadic<AnyType>:$suffix    // non-arg segment (e.g., 'out')3884  );3885  let results = (outs);3886  let assemblyFormat = [{3887    $callee `(` $prefix `:` type($prefix) `)`3888            `(` $args `:` type($args) `)`3889            `(` $suffix `:` type($suffix) `)` attr-dict3890  }];3891 3892  // Provide stub implementations for the ArgAndResultAttrsOpInterface.3893  let extraClassDeclaration = [{3894    ::mlir::ArrayAttr getArgAttrsAttr() { return {}; }3895    ::mlir::ArrayAttr getResAttrsAttr() { return {}; }3896    void setArgAttrsAttr(::mlir::ArrayAttr) {}3897    void setResAttrsAttr(::mlir::ArrayAttr) {}3898    ::mlir::Attribute removeArgAttrsAttr() { return {}; }3899    ::mlir::Attribute removeResAttrsAttr() { return {}; }3900  }];3901 3902  let extraClassDefinition = [{3903    ::mlir::CallInterfaceCallable $cppClass::getCallableForCallee() {3904      if (auto sym = (*this)->getAttrOfType<::mlir::SymbolRefAttr>("callee"))3905        return ::mlir::CallInterfaceCallable(sym);3906      return ::mlir::CallInterfaceCallable();3907    }3908    void $cppClass::setCalleeFromCallable(::mlir::CallInterfaceCallable callee) {3909      if (auto sym = callee.dyn_cast<::mlir::SymbolRefAttr>())3910        (*this)->setAttr("callee", sym);3911      else3912        (*this)->removeAttr("callee");3913    }3914  }];3915}3916 3917 3918#endif // TEST_OPS3919