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-exception 6// 7//===----------------------------------------------------------------------===// 8 9#ifndef TEST_OPS 10#define TEST_OPS 11 12include "mlir/IR/OpBase.td" 13include "mlir/IR/OpAsmInterface.td" 14include "mlir/IR/RegionKindInterface.td" 15include "mlir/IR/SymbolInterfaces.td" 16include "mlir/Interfaces/SideEffectInterfaces.td" 17include "mlir/Interfaces/CallInterfaces.td" 18include "mlir/Interfaces/ControlFlowInterfaces.td" 19include "mlir/Interfaces/InferTypeOpInterface.td" 20include "mlir/Interfaces/SideEffectInterfaces.td" 21 22def Test_Dialect : Dialect { 23 let name = "test"; 24 let cppNamespace = "::mlir"; 25 let hasOperationAttrVerify = 1; 26 let hasRegionArgAttrVerify = 1; 27 let hasRegionResultAttrVerify = 1; 28} 29 30class TEST_Op<string mnemonic, list<OpTrait> traits = []> : 31 Op<Test_Dialect, mnemonic, traits>; 32 33//===----------------------------------------------------------------------===// 34// Test Types 35//===----------------------------------------------------------------------===// 36 37def IntTypesOp : TEST_Op<"int_types"> { 38 let results = (outs 39 AnyI16:$any_i16, 40 SI32:$si32, 41 UI64:$ui64, 42 AnyInteger:$any_int 43 ); 44} 45 46def ComplexF64 : Complex<F64>; 47def ComplexOp : TEST_Op<"complex_f64"> { 48 let results = (outs ComplexF64); 49} 50 51def ComplexTensorOp : TEST_Op<"complex_f64_tensor"> { 52 let results = (outs TensorOf<[ComplexF64]>); 53} 54 55def TupleOp : TEST_Op<"tuple_32_bit"> { 56 let results = (outs TupleOf<[I32, F32]>); 57} 58 59def NestedTupleOp : TEST_Op<"nested_tuple_32_bit"> { 60 let results = (outs NestedTupleOf<[I32, F32]>); 61} 62 63def TakesStaticMemRefOp : TEST_Op<"takes_static_memref"> { 64 let arguments = (ins AnyStaticShapeMemRef:$x); 65} 66 67def RankLessThan2I8F32MemRefOp : TEST_Op<"rank_less_than_2_I8_F32_memref"> { 68 let results = (outs MemRefRankOf<[I8, F32], [0, 1]>); 69} 70 71def NDTensorOfOp : TEST_Op<"nd_tensor_of"> { 72 let arguments = (ins 73 0DTensorOf<[F32]>:$arg0, 74 1DTensorOf<[F32]>:$arg1, 75 2DTensorOf<[I16]>:$arg2, 76 3DTensorOf<[I16]>:$arg3, 77 4DTensorOf<[I16]>:$arg4 78 ); 79} 80 81def RankedTensorOp : TEST_Op<"ranked_tensor_op"> { 82 let arguments = (ins AnyRankedTensor:$input); 83} 84 85def MultiTensorRankOf : TEST_Op<"multi_tensor_rank_of"> { 86 let arguments = (ins 87 TensorRankOf<[I8, I32, F32], [0, 1]>:$arg0 88 ); 89} 90 91def TEST_TestType : DialectType<Test_Dialect, 92 CPred<"$_self.isa<::mlir::TestType>()">, "test">, 93 BuildableType<"$_builder.getType<::mlir::TestType>()">; 94 95//===----------------------------------------------------------------------===// 96// Test Symbols 97//===----------------------------------------------------------------------===// 98 99def SymbolOp : TEST_Op<"symbol", [Symbol]> { 100 let summary = "operation which defines a new symbol"; 101 let arguments = (ins StrAttr:$sym_name, 102 OptionalAttr<StrAttr>:$sym_visibility); 103} 104 105def SymbolScopeOp : TEST_Op<"symbol_scope", 106 [SymbolTable, SingleBlockImplicitTerminator<"TerminatorOp">]> { 107 let summary = "operation which defines a new symbol table"; 108 let regions = (region SizedRegion<1>:$region); 109} 110 111def SymbolTableRegionOp : TEST_Op<"symbol_table_region", [SymbolTable]> { 112 let summary = "operation which defines a new symbol table without a " 113 "restriction on a terminator"; 114 let regions = (region SizedRegion<1>:$region); 115} 116 117//===----------------------------------------------------------------------===// 118// Test Operands 119//===----------------------------------------------------------------------===// 120 121def MixedNormalVariadicOperandOp : TEST_Op< 122 "mixed_normal_variadic_operand", [SameVariadicOperandSize]> { 123 let arguments = (ins 124 Variadic<AnyTensor>:$input1, 125 AnyTensor:$input2, 126 Variadic<AnyTensor>:$input3 127 ); 128} 129def VariadicWithSameOperandsResult : 130 TEST_Op<"variadic_with_same_operand_results", 131 [SameOperandsAndResultType]> { 132 let arguments = (ins Variadic<AnySignlessInteger>:$operands); 133 let results = (outs AnySignlessInteger:$result); 134} 135 136//===----------------------------------------------------------------------===// 137// Test Results 138//===----------------------------------------------------------------------===// 139 140def MixedNormalVariadicResults : TEST_Op< 141 "mixed_normal_variadic_result", [SameVariadicResultSize]> { 142 let results = (outs 143 Variadic<AnyTensor>:$output1, 144 AnyTensor:$output2, 145 Variadic<AnyTensor>:$output3 146 ); 147} 148 149//===----------------------------------------------------------------------===// 150// Test Attributes 151//===----------------------------------------------------------------------===// 152 153def NonNegIntAttrOp : TEST_Op<"non_negative_int_attr"> { 154 let arguments = (ins 155 Confined<I32Attr, [IntNonNegative]>:$i32attr, 156 Confined<I64Attr, [IntNonNegative]>:$i64attr 157 ); 158} 159 160def PositiveIntAttrOp : TEST_Op<"positive_int_attr"> { 161 let arguments = (ins 162 Confined<I32Attr, [IntPositive]>:$i32attr, 163 Confined<I64Attr, [IntPositive]>:$i64attr 164 ); 165} 166 167def TypeArrayAttrOp : TEST_Op<"type_array_attr"> { 168 let arguments = (ins TypeArrayAttr:$attr); 169} 170def TypeArrayAttrWithDefaultOp : TEST_Op<"type_array_attr_with_default"> { 171 let arguments = (ins DefaultValuedAttr<TypeArrayAttr, "{}">:$attr); 172} 173def TypeStringAttrWithTypeOp : TEST_Op<"string_attr_with_type"> { 174 let arguments = (ins TypedStrAttr<AnyType>:$attr); 175 let assemblyFormat = "$attr attr-dict"; 176} 177 178def StrCaseA: StrEnumAttrCase<"A">; 179def StrCaseB: StrEnumAttrCase<"B">; 180 181def SomeStrEnum: StrEnumAttr< 182 "SomeStrEnum", "", [StrCaseA, StrCaseB]>; 183 184def StrEnumAttrOp : TEST_Op<"str_enum_attr"> { 185 let arguments = (ins SomeStrEnum:$attr); 186 let results = (outs I32:$val); 187} 188 189def I32Case5: I32EnumAttrCase<"case5", 5>; 190def I32Case10: I32EnumAttrCase<"case10", 10>; 191 192def SomeI32Enum: I32EnumAttr< 193 "SomeI32Enum", "", [I32Case5, I32Case10]>; 194 195def I32EnumAttrOp : TEST_Op<"i32_enum_attr"> { 196 let arguments = (ins SomeI32Enum:$attr); 197 let results = (outs I32:$val); 198} 199 200def I64Case5: I64EnumAttrCase<"case5", 5>; 201def I64Case10: I64EnumAttrCase<"case10", 10>; 202 203def SomeI64Enum: I64EnumAttr< 204 "SomeI64Enum", "", [I64Case5, I64Case10]>; 205 206def I64EnumAttrOp : TEST_Op<"i64_enum_attr"> { 207 let arguments = (ins SomeI64Enum:$attr); 208 let results = (outs I32:$val); 209} 210 211def SomeStructAttr : StructAttr<"SomeStructAttr", Test_Dialect, [ 212 StructFieldAttr<"some_field", I64Attr>, 213 StructFieldAttr<"some_other_field", I64Attr> 214]> {} 215 216def StructAttrOp : TEST_Op<"struct_attr"> { 217 let arguments = (ins SomeStructAttr:$the_struct_attr); 218 let results = (outs); 219} 220 221def IntAttrOp : TEST_Op<"int_attrs"> { 222 let arguments = (ins 223 AnyI32Attr:$any_i32_attr, 224 IndexAttr:$index_attr, 225 UI32Attr:$ui32_attr, 226 SI32Attr:$si32_attr 227 ); 228} 229 230def FloatElementsAttrOp : TEST_Op<"float_elements_attr"> { 231 let arguments = (ins 232 RankedF32ElementsAttr<[2]>:$scalar_f32_attr, 233 RankedF64ElementsAttr<[4, 8]>:$tensor_f64_attr 234 ); 235} 236 237// A pattern that updates dense<[3.0, 4.0]> to dense<[5.0, 6.0]>. 238// This tests both matching and generating float elements attributes. 239def UpdateFloatElementsAttr : Pat< 240 (FloatElementsAttrOp 241 ConstantAttr<RankedF32ElementsAttr<[2]>, "{3.0f, 4.0f}">:$f32attr, 242 $f64attr), 243 (FloatElementsAttrOp 244 ConstantAttr<RankedF32ElementsAttr<[2]>, "{5.0f, 6.0f}">:$f32attr, 245 $f64attr)>; 246 247def IntElementsAttrOp : TEST_Op<"int_elements_attr"> { 248 let arguments = (ins 249 AnyI32ElementsAttr:$any_i32_attr, 250 I32ElementsAttr:$i32_attr 251 ); 252} 253 254def RankedIntElementsAttrOp : TEST_Op<"ranked_int_elements_attr"> { 255 let arguments = (ins 256 RankedI32ElementsAttr<[2]>:$vector_i32_attr, 257 RankedI64ElementsAttr<[4, 8]>:$matrix_i64_attr 258 ); 259} 260 261def DerivedTypeAttrOp : TEST_Op<"derived_type_attr", []> { 262 let results = (outs AnyTensor:$output); 263 DerivedTypeAttr element_dtype = 264 DerivedTypeAttr<"return getElementTypeOrSelf(output().getType());">; 265 DerivedAttr size = DerivedAttr<"int", 266 "return output().getType().cast<ShapedType>().getSizeInBits();", 267 "$_builder.getI32IntegerAttr($_self)">; 268} 269 270def StringElementsAttrOp : TEST_Op<"string_elements_attr"> { 271 let arguments = (ins 272 StringElementsAttr:$scalar_string_attr 273 ); 274} 275 276//===----------------------------------------------------------------------===// 277// Test Attribute Constraints 278//===----------------------------------------------------------------------===// 279 280def SymbolRefOp : TEST_Op<"symbol_ref_attr"> { 281 let arguments = (ins 282 Confined<FlatSymbolRefAttr, [ReferToOp<"FuncOp">]>:$symbol 283 ); 284} 285 286//===----------------------------------------------------------------------===// 287// Test Regions 288//===----------------------------------------------------------------------===// 289 290def OneRegionOp : TEST_Op<"one_region_op", []> { 291 let regions = (region AnyRegion); 292} 293 294def TwoRegionOp : TEST_Op<"two_region_op", []> { 295 let regions = (region AnyRegion, AnyRegion); 296} 297 298def SizedRegionOp : TEST_Op<"sized_region_op", []> { 299 let regions = (region SizedRegion<2>:$my_region, SizedRegion<1>); 300} 301 302//===----------------------------------------------------------------------===// 303// Test Call Interfaces 304//===----------------------------------------------------------------------===// 305 306def ConversionCallOp : TEST_Op<"conversion_call_op", 307 [CallOpInterface]> { 308 let arguments = (ins Variadic<AnyType>:$inputs, SymbolRefAttr:$callee); 309 let results = (outs Variadic<AnyType>); 310 311 let extraClassDeclaration = [{ 312 /// Get the argument operands to the called function. 313 operand_range getArgOperands() { return inputs(); } 314 315 /// Return the callee of this operation. 316 CallInterfaceCallable getCallableForCallee() { 317 return getAttrOfType<SymbolRefAttr>("callee"); 318 } 319 }]; 320} 321 322def FunctionalRegionOp : TEST_Op<"functional_region_op", 323 [CallableOpInterface]> { 324 let regions = (region AnyRegion:$body); 325 let results = (outs FunctionType); 326 327 let extraClassDeclaration = [{ 328 Region *getCallableRegion() { return &body(); } 329 ArrayRef<Type> getCallableResults() { 330 return getType().cast<FunctionType>().getResults(); 331 } 332 }]; 333} 334 335 336def FoldToCallOp : TEST_Op<"fold_to_call_op"> { 337 let arguments = (ins FlatSymbolRefAttr:$callee); 338 let hasCanonicalizer = 1; 339} 340 341//===----------------------------------------------------------------------===// 342// Test Traits 343//===----------------------------------------------------------------------===// 344 345def SameOperandElementTypeOp : TEST_Op<"same_operand_element_type", 346 [SameOperandsElementType]> { 347 let arguments = (ins AnyType, AnyType); 348 let results = (outs AnyType); 349} 350 351def SameOperandAndResultElementTypeOp : TEST_Op<"same_operand_and_result_element_type", 352 [SameOperandsAndResultElementType]> { 353 let arguments = (ins Variadic<AnyType>); 354 let results = (outs Variadic<AnyType>); 355} 356 357def SameOperandShapeOp : TEST_Op<"same_operand_shape", [SameOperandsShape]> { 358 let arguments = (ins Variadic<AnyShaped>); 359} 360 361def SameOperandAndResultShapeOp : TEST_Op<"same_operand_and_result_shape", 362 [SameOperandsAndResultShape]> { 363 let arguments = (ins Variadic<AnyShaped>); 364 let results = (outs Variadic<AnyShaped>); 365} 366 367def SameOperandAndResultTypeOp : TEST_Op<"same_operand_and_result_type", 368 [SameOperandsAndResultType]> { 369 let arguments = (ins Variadic<AnyType>); 370 let results = (outs Variadic<AnyType>); 371} 372 373def ArgAndResHaveFixedElementTypesOp : 374 TEST_Op<"arg_and_res_have_fixed_element_types", 375 [PredOpTrait<"fixed type combination", 376 And<[ElementTypeIsPred<"x", I32>, 377 ElementTypeIsPred<"y", F32>]>>, 378 ElementTypeIs<"res", I16>]> { 379 let arguments = (ins 380 AnyShaped:$x, AnyShaped:$y); 381 let results = (outs AnyShaped:$res); 382} 383 384def OperandsHaveSameElementType : TEST_Op<"operands_have_same_element_type", [ 385 AllElementTypesMatch<["x", "y"]>]> { 386 let arguments = (ins AnyType:$x, AnyType:$y); 387} 388 389def OperandZeroAndResultHaveSameElementType : TEST_Op< 390 "operand0_and_result_have_same_element_type", 391 [AllElementTypesMatch<["x", "res"]>]> { 392 let arguments = (ins AnyType:$x, AnyType:$y); 393 let results = (outs AnyType:$res); 394} 395 396def OperandsHaveSameType : 397 TEST_Op<"operands_have_same_type", [AllTypesMatch<["x", "y"]>]> { 398 let arguments = (ins AnyType:$x, AnyType:$y); 399} 400 401def OperandZeroAndResultHaveSameType : 402 TEST_Op<"operand0_and_result_have_same_type", 403 [AllTypesMatch<["x", "res"]>]> { 404 let arguments = (ins AnyType:$x, AnyType:$y); 405 let results = (outs AnyType:$res); 406} 407 408def OperandsHaveSameRank : 409 TEST_Op<"operands_have_same_rank", [AllRanksMatch<["x", "y"]>]> { 410 let arguments = (ins AnyShaped:$x, AnyShaped:$y); 411} 412 413def OperandZeroAndResultHaveSameRank : 414 TEST_Op<"operand0_and_result_have_same_rank", 415 [AllRanksMatch<["x", "res"]>]> { 416 let arguments = (ins AnyShaped:$x, AnyShaped:$y); 417 let results = (outs AnyShaped:$res); 418} 419 420def OperandZeroAndResultHaveSameShape : 421 TEST_Op<"operand0_and_result_have_same_shape", 422 [AllShapesMatch<["x", "res"]>]> { 423 let arguments = (ins AnyShaped:$x, AnyShaped:$y); 424 let results = (outs AnyShaped:$res); 425} 426 427def OperandZeroAndResultHaveSameElementCount : 428 TEST_Op<"operand0_and_result_have_same_element_count", 429 [AllElementCountsMatch<["x", "res"]>]> { 430 let arguments = (ins AnyShaped:$x, AnyShaped:$y); 431 let results = (outs AnyShaped:$res); 432} 433 434def FourEqualsFive : 435 TEST_Op<"four_equals_five", [AllMatch<["5", "4"], "4 equals 5">]>; 436 437def OperandRankEqualsResultSize : 438 TEST_Op<"operand_rank_equals_result_size", 439 [AllMatch<[Rank<"operand">.result, ElementCount<"result">.result], 440 "operand rank equals result size">]> { 441 let arguments = (ins AnyShaped:$operand); 442 let results = (outs AnyShaped:$result); 443} 444 445def IfFirstOperandIsNoneThenSoIsSecond : 446 TEST_Op<"if_first_operand_is_none_then_so_is_second", [PredOpTrait< 447 "has either both none type operands or first is not none", 448 Or<[ 449 And<[TypeIsPred<"x", NoneType>, TypeIsPred<"y", NoneType>]>, 450 Neg<TypeIsPred<"x", NoneType>>]>>]> { 451 let arguments = (ins AnyType:$x, AnyType:$y); 452} 453 454def BroadcastableOp : TEST_Op<"broadcastable", [ResultsBroadcastableShape]> { 455 let arguments = (ins Variadic<AnyTensor>); 456 let results = (outs AnyTensor); 457} 458 459// HasParent trait 460def ParentOp : TEST_Op<"parent"> { 461 let regions = (region AnyRegion); 462} 463def ChildOp : TEST_Op<"child", [HasParent<"ParentOp">]>; 464 465// ParentOneOf trait 466def ParentOp1 : TEST_Op<"parent1"> { 467 let regions = (region AnyRegion); 468} 469def ChildWithParentOneOf : TEST_Op<"child_with_parent_one_of", 470 [ParentOneOf<["ParentOp", "ParentOp1"]>]>; 471 472def TerminatorOp : TEST_Op<"finish", [Terminator]>; 473def SingleBlockImplicitTerminatorOp : TEST_Op<"SingleBlockImplicitTerminator", 474 [SingleBlockImplicitTerminator<"TerminatorOp">]> { 475 let regions = (region SizedRegion<1>:$region); 476} 477 478def I32ElementsAttrOp : TEST_Op<"i32ElementsAttr"> { 479 let arguments = (ins I32ElementsAttr:$attr); 480} 481 482def IndexElementsAttrOp : TEST_Op<"indexElementsAttr"> { 483 let arguments = (ins IndexElementsAttr:$attr); 484} 485 486def OpWithInferTypeInterfaceOp : TEST_Op<"op_with_infer_type_if", [ 487 DeclareOpInterfaceMethods<InferTypeOpInterface>]> { 488 let arguments = (ins AnyTensor, AnyTensor); 489 let results = (outs AnyTensor); 490} 491 492def InferTensorType : NativeOpTrait<"InferTensorType">; 493def OpWithShapedTypeInferTypeInterfaceOp : TEST_Op<"op_with_shaped_type_infer_type_if", 494 [ 495 // Op implements infer type op interface. 496 InferTypeOpInterface, 497 // The op will have methods implementing the ShapedType type infer interface. 498 DeclareOpInterfaceMethods<InferShapedTypeOpInterface>, 499 // The op produces tensors and will use the ShapedType type infer interface 500 // along with knowledge that it is producing Tensors to infer shape. 501 InferTensorType 502 ]> { 503 let arguments = (ins AnyTensor, AnyTensor); 504 let results = (outs AnyTensor); 505 506 let extraClassDeclaration = [{ 507 LogicalResult reifyReturnTypeShapes(OpBuilder &builder, 508 SmallVectorImpl<Value> &shapes); 509 }]; 510} 511 512def IsNotScalar : Constraint<CPred<"$0.getType().getRank() != 0">>; 513 514def UpdateAttr : Pat<(I32ElementsAttrOp $attr), 515 (I32ElementsAttrOp ConstantAttr<I32ElementsAttr, "0">), 516 [(IsNotScalar $attr)]>; 517 518def TestBranchOp : TEST_Op<"br", 519 [DeclareOpInterfaceMethods<BranchOpInterface>, Terminator]> { 520 let arguments = (ins Variadic<AnyType>:$targetOperands); 521 let successors = (successor AnySuccessor:$target); 522} 523 524def AttrSizedOperandOp : TEST_Op<"attr_sized_operands", 525 [AttrSizedOperandSegments]> { 526 let arguments = (ins 527 Variadic<I32>:$a, 528 Variadic<I32>:$b, 529 I32:$c, 530 Variadic<I32>:$d, 531 I32ElementsAttr:$operand_segment_sizes 532 ); 533} 534 535def AttrSizedResultOp : TEST_Op<"attr_sized_results", 536 [AttrSizedResultSegments]> { 537 let arguments = (ins 538 I32ElementsAttr:$result_segment_sizes 539 ); 540 let results = (outs 541 Variadic<I32>:$a, 542 Variadic<I32>:$b, 543 I32:$c, 544 Variadic<I32>:$d 545 ); 546} 547 548// This is used to test encoding of a string attribute into an SSA name of a 549// pretty printed value name. 550def StringAttrPrettyNameOp 551 : TEST_Op<"string_attr_pretty_name", 552 [DeclareOpInterfaceMethods<OpAsmOpInterface>]> { 553 let arguments = (ins StrArrayAttr:$names); 554 let results = (outs Variadic<I32>:$r); 555 556 let printer = [{ return ::print(p, *this); }]; 557 let parser = [{ return ::parse$cppClass(parser, result); }]; 558} 559 560//===----------------------------------------------------------------------===// 561// Test Locations 562//===----------------------------------------------------------------------===// 563 564def TestLocationSrcOp : TEST_Op<"loc_src"> { 565 let arguments = (ins I32:$input); 566 let results = (outs I32:$output); 567} 568 569def TestLocationDstOp : TEST_Op<"loc_dst", [SameOperandsAndResultType]> { 570 let arguments = (ins I32:$input); 571 let results = (outs I32:$output); 572} 573 574//===----------------------------------------------------------------------===// 575// Test Patterns 576//===----------------------------------------------------------------------===// 577 578def OpA : TEST_Op<"op_a"> { 579 let arguments = (ins I32, I32Attr:$attr); 580 let results = (outs I32); 581} 582 583def OpB : TEST_Op<"op_b"> { 584 let arguments = (ins I32, I32Attr:$attr); 585 let results = (outs I32); 586} 587 588// Test named pattern. 589def TestNamedPatternRule : Pat<(OpA $input, $attr), (OpB $input, $attr)>; 590 591// Test with fused location. 592def : Pat<(OpA (OpA $input, $attr), $bttr), (OpB $input, $bttr)>; 593 594// Test added benefit. 595def OpD : TEST_Op<"op_d">, Arguments<(ins I32)>, Results<(outs I32)>; 596def OpE : TEST_Op<"op_e">, Arguments<(ins I32)>, Results<(outs I32)>; 597def OpF : TEST_Op<"op_f">, Arguments<(ins I32)>, Results<(outs I32)>; 598def OpG : TEST_Op<"op_g">, Arguments<(ins I32)>, Results<(outs I32)>; 599// Verify that bumping benefit results in selecting different op. 600def : Pat<(OpD $input), (OpE $input)>; 601def : Pat<(OpD $input), (OpF $input), [], (addBenefit 10)>; 602// Verify that patterns with more source nodes are selected before those with fewer. 603def : Pat<(OpG $input), (OpB $input, ConstantAttr<I32Attr, "20">:$attr)>; 604def : Pat<(OpG (OpG $input)), (OpB $input, ConstantAttr<I32Attr, "34">:$attr)>; 605 606// Test patterns for zero-result op. 607def OpH : TEST_Op<"op_h">, Arguments<(ins I32)>, Results<(outs)>; 608def OpI : TEST_Op<"op_i">, Arguments<(ins I32)>, Results<(outs)>; 609def : Pat<(OpH $input), (OpI $input)>; 610 611// Test patterns for zero-input op. 612def OpJ : TEST_Op<"op_j">, Arguments<(ins)>, Results<(outs I32)>; 613def OpK : TEST_Op<"op_k">, Arguments<(ins)>, Results<(outs I32)>; 614def : Pat<(OpJ), (OpK)>; 615 616// Test that natives calls are only called once during rewrites. 617def OpM : TEST_Op<"op_m"> { 618 let arguments = (ins I32, OptionalAttr<I32Attr>:$optional_attr); 619 let results = (outs I32); 620} 621 622def OpN : TEST_Op<"op_n"> { 623 let arguments = (ins I32, I32); 624 let results = (outs I32); 625} 626 627def OpO : TEST_Op<"op_o"> { 628 let arguments = (ins I32); 629 let results = (outs I32); 630} 631 632def OpP : TEST_Op<"op_p"> { 633 let arguments = (ins I32, I32, I32, I32, I32, I32); 634 let results = (outs I32); 635} 636 637// Test same operand name enforces equality condition check. 638def TestEqualArgsPattern : Pat<(OpN $a, $a), (OpO $a)>; 639 640// Test when equality is enforced at different depth. 641def TestNestedOpEqualArgsPattern : 642 Pat<(OpN $b, (OpP $a, $b, $c, $d, $e, $f)), (replaceWithValue $b)>; 643 644// Test multiple equal arguments check enforced. 645def TestMultipleEqualArgsPattern : 646 Pat<(OpP $a, $b, $a, $a, $b, $c), (OpN $c, $b)>; 647 648// Test for memrefs normalization of an op with normalizable memrefs. 649def OpNorm : TEST_Op<"op_norm", [MemRefsNormalizable]> { 650 let arguments = (ins AnyMemRef:$X, AnyMemRef:$Y); 651} 652// Test for memrefs normalization of an op without normalizable memrefs. 653def OpNonNorm : TEST_Op<"op_nonnorm"> { 654 let arguments = (ins AnyMemRef:$X, AnyMemRef:$Y); 655} 656 657// Test for memrefs normalization of an op with a reference to a function 658// symbol. 659def OpFuncRef : TEST_Op<"op_funcref"> { 660 let summary = "Test op with a reference to a function symbol"; 661 let description = [{ 662 The "test.op_funcref" is a test op with a reference to a function symbol. 663 }]; 664 let builders = [OpBuilder<[{FuncOp function}]>]; 665} 666 667// Pattern add the argument plus a increasing static number hidden in 668// OpMTest function. That value is set into the optional argument. 669// That way, we will know if operations is called once or twice. 670def OpMGetNullAttr : NativeCodeCall<"Attribute()">; 671def OpMAttributeIsNull : Constraint<CPred<"! ($_self)">, "Attribute is null">; 672def OpMVal : NativeCodeCall<"OpMTest($_builder, $0)">; 673def : Pat<(OpM $attr, $optAttr), (OpM $attr, (OpMVal $attr) ), 674 [(OpMAttributeIsNull:$optAttr)]>; 675 676// Test `$_` for ignoring op argument match. 677def TestIgnoreArgMatchSrcOp : TEST_Op<"ignore_arg_match_src"> { 678 let arguments = (ins 679 AnyType:$a, AnyType:$b, AnyType:$c, 680 AnyAttr:$d, AnyAttr:$e, AnyAttr:$f); 681} 682def TestIgnoreArgMatchDstOp : TEST_Op<"ignore_arg_match_dst"> { 683 let arguments = (ins AnyType:$b, AnyAttr:$f); 684} 685def : Pat<(TestIgnoreArgMatchSrcOp $_, $b, I32, I64Attr:$_, $_, $f), 686 (TestIgnoreArgMatchDstOp $b, $f)>; 687 688def OpInterleavedOperandAttribute1 : TEST_Op<"interleaved_operand_attr1"> { 689 let arguments = (ins 690 I32:$input1, 691 I64Attr:$attr1, 692 I32:$input2, 693 I64Attr:$attr2 694 ); 695} 696 697def OpInterleavedOperandAttribute2 : TEST_Op<"interleaved_operand_attr2"> { 698 let arguments = (ins 699 I32:$input1, 700 I64Attr:$attr1, 701 I32:$input2, 702 I64Attr:$attr2 703 ); 704} 705 706def ManyArgsOp : TEST_Op<"many_arguments"> { 707 let arguments = (ins 708 I32:$input1, I32:$input2, I32:$input3, I32:$input4, I32:$input5, 709 I32:$input6, I32:$input7, I32:$input8, I32:$input9, 710 I64Attr:$attr1, I64Attr:$attr2, I64Attr:$attr3, I64Attr:$attr4, 711 I64Attr:$attr5, I64Attr:$attr6, I64Attr:$attr7, I64Attr:$attr8, 712 I64Attr:$attr9 713 ); 714} 715 716// Test that DRR does not blow up when seeing lots of arguments. 717def : Pat<(ManyArgsOp 718 $input1, $input2, $input3, $input4, $input5, 719 $input6, $input7, $input8, $input9, 720 ConstantAttr<I64Attr, "42">, 721 $attr2, $attr3, $attr4, $attr5, $attr6, 722 $attr7, $attr8, $attr9), 723 (ManyArgsOp 724 $input1, $input2, $input3, $input4, $input5, 725 $input6, $input7, $input8, $input9, 726 ConstantAttr<I64Attr, "24">, 727 $attr2, $attr3, $attr4, $attr5, $attr6, 728 $attr7, $attr8, $attr9)>; 729 730// Test that we can capture and reference interleaved operands and attributes. 731def : Pat<(OpInterleavedOperandAttribute1 $input1, $attr1, $input2, $attr2), 732 (OpInterleavedOperandAttribute2 $input1, $attr1, $input2, $attr2)>; 733 734// Test NativeCodeCall. 735def OpNativeCodeCall1 : TEST_Op<"native_code_call1"> { 736 let arguments = (ins 737 I32:$input1, I32:$input2, 738 BoolAttr:$choice, 739 I64Attr:$attr1, I64Attr:$attr2 740 ); 741 let results = (outs I32); 742} 743def OpNativeCodeCall2 : TEST_Op<"native_code_call2"> { 744 let arguments = (ins I32:$input, I64ArrayAttr:$attr); 745 let results = (outs I32); 746} 747// Native code call to invoke a C++ function 748def CreateOperand: NativeCodeCall<"chooseOperand($0, $1, $2)">; 749// Native code call to invoke a C++ expression 750def CreateArrayAttr: NativeCodeCall<"$_builder.getArrayAttr({$0, $1})">; 751// Test that we can use NativeCodeCall to create operand and attribute. 752// This pattern chooses between $input1 and $input2 according to $choice and 753// it combines $attr1 and $attr2 into an array attribute. 754def : Pat<(OpNativeCodeCall1 $input1, $input2, 755 ConstBoolAttrTrue:$choice, $attr1, $attr2), 756 (OpNativeCodeCall2 (CreateOperand $input1, $input2, $choice), 757 (CreateArrayAttr $attr1, $attr2))>; 758// Note: the following is just for testing purpose. 759// Should use the replaceWithValue directive instead. 760def UseOpResult: NativeCodeCall<"$0">; 761// Test that we can use NativeCodeCall to create result. 762def : Pat<(OpNativeCodeCall1 $input1, $input2, 763 ConstBoolAttrFalse, $attr1, $attr2), 764 (UseOpResult $input2)>; 765 766def OpNativeCodeCall3 : TEST_Op<"native_code_call3"> { 767 let arguments = (ins I32:$input); 768 let results = (outs I32); 769} 770// Test that NativeCodeCall is not ignored if it is not used to directly 771// replace the matched root op. 772def : Pattern<(OpNativeCodeCall3 $input), 773 [(NativeCodeCall<"createOpI($_builder, $_loc, $0)"> $input), 774 (OpK)]>; 775 776// Test AllAttrConstraintsOf. 777def OpAllAttrConstraint1 : TEST_Op<"all_attr_constraint_of1"> { 778 let arguments = (ins I64ArrayAttr:$attr); 779 let results = (outs I32); 780} 781def OpAllAttrConstraint2 : TEST_Op<"all_attr_constraint_of2"> { 782 let arguments = (ins I64ArrayAttr:$attr); 783 let results = (outs I32); 784} 785def Constraint0 : AttrConstraint< 786 CPred<"$_self.cast<ArrayAttr>()[0]." 787 "cast<IntegerAttr>().getInt() == 0">, 788 "[0] == 0">; 789def Constraint1 : AttrConstraint< 790 CPred<"$_self.cast<ArrayAttr>()[1].cast<IntegerAttr>().getInt() == 1">, 791 "[1] == 1">; 792def : Pat<(OpAllAttrConstraint1 793 AllAttrConstraintsOf<[Constraint0, Constraint1]>:$attr), 794 (OpAllAttrConstraint2 $attr)>; 795 796// Op for testing RewritePattern removing op with inner ops. 797def TestOpWithRegionPattern : TEST_Op<"op_with_region_pattern"> { 798 let regions = (region SizedRegion<1>:$region); 799 let hasCanonicalizer = 1; 800} 801 802// Op for testing trivial removal via folding of op with inner ops and no uses. 803def TestOpWithRegionFoldNoSideEffect : TEST_Op< 804 "op_with_region_fold_no_side_effect", [NoSideEffect]> { 805 let regions = (region SizedRegion<1>:$region); 806} 807 808// Op for testing folding of outer op with inner ops. 809def TestOpWithRegionFold : TEST_Op<"op_with_region_fold"> { 810 let arguments = (ins I32:$operand); 811 let results = (outs I32); 812 let regions = (region SizedRegion<1>:$region); 813 let hasFolder = 1; 814} 815 816def TestOpWithVariadicResultsAndFolder: TEST_Op<"op_with_variadic_results_and_folder"> { 817 let arguments = (ins Variadic<I32>:$operands); 818 let results = (outs Variadic<I32>); 819 let hasFolder = 1; 820} 821 822def TestCommutativeOp : TEST_Op<"op_commutative", [Commutative]> { 823 let arguments = (ins I32:$op1, I32:$op2, I32:$op3, I32:$op4); 824 let results = (outs I32); 825} 826 827def TestInvolutionTraitNoOperationFolderOp 828 : TEST_Op<"op_involution_trait_no_operation_fold", 829 [SameOperandsAndResultType, NoSideEffect, Involution]> { 830 let arguments = (ins I32:$op1); 831 let results = (outs I32); 832} 833 834def TestInvolutionTraitFailingOperationFolderOp 835 : TEST_Op<"op_involution_trait_failing_operation_fold", 836 [SameOperandsAndResultType, NoSideEffect, Involution]> { 837 let arguments = (ins I32:$op1); 838 let results = (outs I32); 839 let hasFolder = 1; 840} 841 842def TestInvolutionTraitSuccesfulOperationFolderOp 843 : TEST_Op<"op_involution_trait_succesful_operation_fold", 844 [SameOperandsAndResultType, NoSideEffect, Involution]> { 845 let arguments = (ins I32:$op1); 846 let results = (outs I32); 847 let hasFolder = 1; 848} 849 850def TestOpInPlaceFoldAnchor : TEST_Op<"op_in_place_fold_anchor"> { 851 let arguments = (ins I32); 852 let results = (outs I32); 853} 854 855def TestOpInPlaceFold : TEST_Op<"op_in_place_fold"> { 856 let arguments = (ins I32:$op, I32Attr:$attr); 857 let results = (outs I32); 858 let hasFolder = 1; 859} 860 861//===----------------------------------------------------------------------===// 862// Test Patterns (Symbol Binding) 863 864// Test symbol binding. 865def OpSymbolBindingA : TEST_Op<"symbol_binding_a", []> { 866 let arguments = (ins I32:$operand, I64Attr:$attr); 867 let results = (outs I32); 868} 869def OpSymbolBindingB : TEST_Op<"symbol_binding_b", []> { 870 let arguments = (ins I32:$operand); 871 let results = (outs I32); 872} 873def OpSymbolBindingC : TEST_Op<"symbol_binding_c", []> { 874 let arguments = (ins I32:$operand); 875 let results = (outs I32); 876 let builders = OpSymbolBindingB.builders; 877} 878def OpSymbolBindingD : TEST_Op<"symbol_binding_d", []> { 879 let arguments = (ins I32:$input1, I32:$input2, I64Attr:$attr); 880 let results = (outs I32); 881} 882def HasOneUse: Constraint<CPred<"$0.hasOneUse()">, "has one use">; 883def : Pattern< 884 // Bind to source pattern op operand/attribute/result 885 (OpSymbolBindingA:$res_a $operand, $attr), [ 886 // Bind to auxiliary op result 887 (OpSymbolBindingC:$res_c (OpSymbolBindingB:$res_b $operand)), 888 889 // Use bound symbols in resultant ops 890 (OpSymbolBindingD $res_b, $res_c, $attr)], 891 // Use bound symbols in additional constraints 892 [(HasOneUse $res_a)]>; 893 894def OpSymbolBindingNoResult : TEST_Op<"symbol_binding_no_result", []> { 895 let arguments = (ins I32:$operand); 896} 897 898// Test that we can bind to an op without results and reference it later. 899def : Pat<(OpSymbolBindingNoResult:$op $operand), 900 (NativeCodeCall<"handleNoResultOp($_builder, $0)"> $op)>; 901 902//===----------------------------------------------------------------------===// 903// Test Patterns (Attributes) 904 905// Test matching against op attributes. 906def OpAttrMatch1 : TEST_Op<"match_op_attribute1"> { 907 let arguments = (ins 908 I32Attr:$required_attr, 909 OptionalAttr<I32Attr>:$optional_attr, 910 DefaultValuedAttr<I32Attr, "42">:$default_valued_attr, 911 I32Attr:$more_attr 912 ); 913 let results = (outs I32); 914} 915def OpAttrMatch2 : TEST_Op<"match_op_attribute2"> { 916 let arguments = OpAttrMatch1.arguments; 917 let results = (outs I32); 918} 919def MoreConstraint : AttrConstraint< 920 CPred<"$_self.cast<IntegerAttr>().getInt() == 4">, "more constraint">; 921def : Pat<(OpAttrMatch1 $required, $optional, $default_valued, 922 MoreConstraint:$more), 923 (OpAttrMatch2 $required, $optional, $default_valued, $more)>; 924 925// Test unit attrs. 926def OpAttrMatch3 : TEST_Op<"match_op_attribute3"> { 927 let arguments = (ins UnitAttr:$attr); 928 let results = (outs I32); 929} 930def OpAttrMatch4 : TEST_Op<"match_op_attribute4"> { 931 let arguments = (ins UnitAttr:$attr1, UnitAttr:$attr2); 932 let results = (outs I32); 933} 934def : Pat<(OpAttrMatch3 $attr), (OpAttrMatch4 ConstUnitAttr, $attr)>; 935 936// Test with constant attr. 937def OpC : TEST_Op<"op_c">, Arguments<(ins I32)>, Results<(outs I32)>; 938def : Pat<(OpC $input), (OpB $input, ConstantAttr<I32Attr, "17">:$attr)>; 939 940// Test string enum attribute in rewrites. 941def : Pat<(StrEnumAttrOp StrCaseA), (StrEnumAttrOp StrCaseB)>; 942// Test integer enum attribute in rewrites. 943def : Pat<(I32EnumAttrOp I32Case5), (I32EnumAttrOp I32Case10)>; 944def : Pat<(I64EnumAttrOp I64Case5), (I64EnumAttrOp I64Case10)>; 945 946//===----------------------------------------------------------------------===// 947// Test Patterns (Multi-result Ops) 948 949def MultiResultOpKind1: I64EnumAttrCase<"kind1", 1>; 950def MultiResultOpKind2: I64EnumAttrCase<"kind2", 2>; 951def MultiResultOpKind3: I64EnumAttrCase<"kind3", 3>; 952def MultiResultOpKind4: I64EnumAttrCase<"kind4", 4>; 953def MultiResultOpKind5: I64EnumAttrCase<"kind5", 5>; 954def MultiResultOpKind6: I64EnumAttrCase<"kind6", 6>; 955 956def MultiResultOpEnum: I64EnumAttr< 957 "MultiResultOpEnum", "Multi-result op kinds", [ 958 MultiResultOpKind1, MultiResultOpKind2, MultiResultOpKind3, 959 MultiResultOpKind4, MultiResultOpKind5, MultiResultOpKind6 960 ]>; 961 962def ThreeResultOp : TEST_Op<"three_result"> { 963 let arguments = (ins MultiResultOpEnum:$kind); 964 let results = (outs I32:$result1, F32:$result2, F32:$result3); 965} 966 967def AnotherThreeResultOp : TEST_Op<"another_three_result"> { 968 let arguments = (ins MultiResultOpEnum:$kind); 969 let results = (outs I32:$result1, F32:$result2, F32:$result3); 970} 971 972def TwoResultOp : TEST_Op<"two_result"> { 973 let arguments = (ins MultiResultOpEnum:$kind); 974 let results = (outs I32:$result1, F32:$result2); 975} 976 977def AnotherTwoResultOp : TEST_Op<"another_two_result"> { 978 let arguments = (ins MultiResultOpEnum:$kind); 979 let results = (outs F32:$result1, F32:$result2); 980} 981 982def OneResultOp1 : TEST_Op<"one_result1"> { 983 let arguments = (ins MultiResultOpEnum:$kind); 984 let results = (outs F32:$result1); 985} 986 987def OneResultOp2 : TEST_Op<"one_result2"> { 988 let arguments = (ins MultiResultOpEnum:$kind); 989 let results = (outs I32:$result1); 990} 991 992def OneResultOp3 : TEST_Op<"one_result3"> { 993 let arguments = (ins F32); 994 let results = (outs I32:$result1); 995} 996 997// Test using multi-result op as a whole 998def : Pat<(ThreeResultOp MultiResultOpKind1), 999 (AnotherThreeResultOp MultiResultOpKind1)>; 1000 1001// Test using multi-result op as a whole for partial replacement 1002def : Pattern<(ThreeResultOp MultiResultOpKind2), 1003 [(TwoResultOp MultiResultOpKind2), 1004 (OneResultOp1 MultiResultOpKind2)]>; 1005def : Pattern<(ThreeResultOp MultiResultOpKind3), 1006 [(OneResultOp2 MultiResultOpKind3), 1007 (AnotherTwoResultOp MultiResultOpKind3)]>; 1008 1009// Test using results separately in a multi-result op 1010def : Pattern<(ThreeResultOp MultiResultOpKind4), 1011 [(TwoResultOp:$res1__0 MultiResultOpKind4), 1012 (OneResultOp1 MultiResultOpKind4), 1013 (TwoResultOp:$res2__1 MultiResultOpKind4)]>; 1014 1015// Test referencing a single value in the value pack 1016// This rule only matches TwoResultOp if its second result has no use. 1017def : Pattern<(TwoResultOp:$res MultiResultOpKind5), 1018 [(OneResultOp2 MultiResultOpKind5), 1019 (OneResultOp1 MultiResultOpKind5)], 1020 [(HasNoUseOf:$res__1)]>; 1021 1022// Test using auxiliary ops for replacing multi-result op 1023def : Pattern< 1024 (ThreeResultOp MultiResultOpKind6), [ 1025 // Auxiliary op generated to help building the final result but not 1026 // directly used to replace the source op's results. 1027 (TwoResultOp:$interm MultiResultOpKind6), 1028 1029 (OneResultOp3 $interm__1), 1030 (AnotherTwoResultOp MultiResultOpKind6) 1031 ]>; 1032 1033//===----------------------------------------------------------------------===// 1034// Test Patterns (Variadic Ops) 1035 1036def OneVResOneVOperandOp1 : TEST_Op<"one_variadic_out_one_variadic_in1"> { 1037 let arguments = (ins Variadic<I32>); 1038 let results = (outs Variadic<I32>); 1039} 1040def OneVResOneVOperandOp2 : TEST_Op<"one_variadic_out_one_variadic_in2"> { 1041 let arguments = (ins Variadic<I32>); 1042 let results = (outs Variadic<I32>); 1043} 1044 1045// Rewrite an op with one variadic operand and one variadic result to 1046// another similar op. 1047def : Pat<(OneVResOneVOperandOp1 $inputs), (OneVResOneVOperandOp2 $inputs)>; 1048 1049def MixedVOperandOp1 : TEST_Op<"mixed_variadic_in1", 1050 [SameVariadicOperandSize]> { 1051 let arguments = (ins 1052 Variadic<I32>:$input1, 1053 F32:$input2, 1054 Variadic<I32>:$input3 1055 ); 1056} 1057 1058def MixedVOperandOp2 : TEST_Op<"mixed_variadic_in2", 1059 [SameVariadicOperandSize]> { 1060 let arguments = (ins 1061 Variadic<I32>:$input1, 1062 F32:$input2, 1063 Variadic<I32>:$input3 1064 ); 1065} 1066 1067// Rewrite an op with both variadic operands and normal operands. 1068def : Pat<(MixedVOperandOp1 $input1, $input2, $input3), 1069 (MixedVOperandOp2 $input1, $input2, $input3)>; 1070 1071def MixedVResultOp1 : TEST_Op<"mixed_variadic_out1", [SameVariadicResultSize]> { 1072 let results = (outs 1073 Variadic<I32>:$output1, 1074 F32:$output2, 1075 Variadic<I32>:$output3 1076 ); 1077} 1078 1079def MixedVResultOp2 : TEST_Op<"mixed_variadic_out2", [SameVariadicResultSize]> { 1080 let results = (outs 1081 Variadic<I32>:$output1, 1082 F32:$output2, 1083 Variadic<I32>:$output3 1084 ); 1085} 1086 1087// Rewrite an op with both variadic results and normal results. 1088// Note that because we are generating the op with a top-level result pattern, 1089// we are able to deduce the correct result types for the generated op using 1090// the information from the matched root op. 1091def : Pat<(MixedVResultOp1), (MixedVResultOp2)>; 1092 1093def OneI32ResultOp : TEST_Op<"one_i32_out"> { 1094 let results = (outs I32); 1095} 1096 1097def MixedVOperandOp3 : TEST_Op<"mixed_variadic_in3", 1098 [SameVariadicOperandSize]> { 1099 let arguments = (ins 1100 I32:$input1, 1101 Variadic<I32>:$input2, 1102 Variadic<I32>:$input3, 1103 I32Attr:$count 1104 ); 1105 1106 let results = (outs I32); 1107} 1108 1109def MixedVResultOp3 : TEST_Op<"mixed_variadic_out3", 1110 [SameVariadicResultSize]> { 1111 let arguments = (ins I32Attr:$count); 1112 1113 let results = (outs 1114 I32:$output1, 1115 Variadic<I32>:$output2, 1116 Variadic<I32>:$output3 1117 ); 1118 1119 // We will use this op in a nested result pattern, where we cannot deduce the 1120 // result type. So need to provide a builder not requiring result types. 1121 let builders = [ 1122 OpBuilder< 1123 "IntegerAttr count", 1124 [{ 1125 auto i32Type = $_builder.getIntegerType(32); 1126 $_state.addTypes(i32Type); // $output1 1127 SmallVector<Type, 4> types(count.getInt(), i32Type); 1128 $_state.addTypes(types); // $output2 1129 $_state.addTypes(types); // $output3 1130 $_state.addAttribute("count", count); 1131 }]> 1132 ]; 1133} 1134 1135// Generates an op with variadic results using nested pattern. 1136def : Pat<(OneI32ResultOp), 1137 (MixedVOperandOp3 1138 (MixedVResultOp3:$results__0 ConstantAttr<I32Attr, "2">), 1139 (replaceWithValue $results__1), 1140 (replaceWithValue $results__2), 1141 ConstantAttr<I32Attr, "2">)>; 1142 1143//===----------------------------------------------------------------------===// 1144// Test Patterns (Location) 1145 1146// Test that we can specify locations for generated ops. 1147def : Pat<(TestLocationSrcOp:$res1 1148 (TestLocationSrcOp:$res2 1149 (TestLocationSrcOp:$res3 $input))), 1150 (TestLocationDstOp 1151 (TestLocationDstOp 1152 (TestLocationDstOp $input, (location $res1)), 1153 (location "named")), 1154 (location "fused", $res2, $res3))>; 1155 1156//===----------------------------------------------------------------------===// 1157// Test Legalization 1158//===----------------------------------------------------------------------===// 1159 1160def Test_LegalizerEnum_Success : StrEnumAttrCase<"Success">; 1161def Test_LegalizerEnum_Failure : StrEnumAttrCase<"Failure">; 1162 1163def Test_LegalizerEnum : StrEnumAttr<"Success", "Failure", 1164 [Test_LegalizerEnum_Success, Test_LegalizerEnum_Failure]>; 1165 1166def ILLegalOpA : TEST_Op<"illegal_op_a">, Results<(outs I32)>; 1167def ILLegalOpB : TEST_Op<"illegal_op_b">, Results<(outs I32)>; 1168def ILLegalOpC : TEST_Op<"illegal_op_c">, Results<(outs I32)>; 1169def ILLegalOpD : TEST_Op<"illegal_op_d">, Results<(outs I32)>; 1170def ILLegalOpE : TEST_Op<"illegal_op_e">, Results<(outs I32)>; 1171def ILLegalOpF : TEST_Op<"illegal_op_f">, Results<(outs I32)>; 1172def LegalOpA : TEST_Op<"legal_op_a">, 1173 Arguments<(ins Test_LegalizerEnum:$status)>, Results<(outs I32)>; 1174def LegalOpB : TEST_Op<"legal_op_b">, Results<(outs I32)>; 1175 1176// Check that the conversion infrastructure can properly undo the creation of 1177// operations where an operation was created before its parent, in this case, 1178// in the parent's builder. 1179def IllegalOpTerminator : TEST_Op<"illegal_op_terminator", [Terminator]>; 1180def IllegalOpWithRegion : TEST_Op<"illegal_op_with_region"> { 1181 let skipDefaultBuilders = 1; 1182 let builders = [OpBuilder<"", 1183 [{ Region *bodyRegion = $_state.addRegion(); 1184 OpBuilder::InsertionGuard g($_builder); 1185 Block *body = $_builder.createBlock(bodyRegion); 1186 $_builder.setInsertionPointToEnd(body); 1187 $_builder.create<IllegalOpTerminator>($_state.location); 1188 }]>]; 1189} 1190def IllegalOpWithRegionAnchor : TEST_Op<"illegal_op_with_region_anchor">; 1191 1192// Check that smaller pattern depths are chosen, i.e. prioritize more direct 1193// mappings. 1194def : Pat<(ILLegalOpA), (LegalOpA Test_LegalizerEnum_Success)>; 1195 1196def : Pat<(ILLegalOpA), (ILLegalOpB)>; 1197def : Pat<(ILLegalOpB), (LegalOpA Test_LegalizerEnum_Failure)>; 1198 1199// Check that the higher benefit pattern is taken for multiple legalizations 1200// with the same depth. 1201def : Pat<(ILLegalOpC), (ILLegalOpD)>; 1202def : Pat<(ILLegalOpD), (LegalOpA Test_LegalizerEnum_Failure)>; 1203 1204def : Pat<(ILLegalOpC), (ILLegalOpE), [], (addBenefit 10)>; 1205def : Pat<(ILLegalOpE), (LegalOpA Test_LegalizerEnum_Success)>; 1206 1207// Check that patterns use the most up-to-date value when being replaced. 1208def TestRewriteOp : TEST_Op<"rewrite">, 1209 Arguments<(ins AnyType)>, Results<(outs AnyType)>; 1210def : Pat<(TestRewriteOp $input), (replaceWithValue $input)>; 1211 1212// Check that patterns can specify bounded recursion when rewriting. 1213def TestRecursiveRewriteOp : TEST_Op<"recursive_rewrite"> { 1214 let arguments = (ins I64Attr:$depth); 1215 let assemblyFormat = "$depth attr-dict"; 1216} 1217 1218//===----------------------------------------------------------------------===// 1219// Test Type Legalization 1220//===----------------------------------------------------------------------===// 1221 1222def TestRegionBuilderOp : TEST_Op<"region_builder">; 1223def TestReturnOp : TEST_Op<"return", [ReturnLike, Terminator]> { 1224 let arguments = (ins Variadic<AnyType>); 1225 let builders = [ 1226 OpBuilder<"", [{ build($_builder, $_state, {}); }]> 1227 ]; 1228} 1229def TestCastOp : TEST_Op<"cast">, 1230 Arguments<(ins Variadic<AnyType>)>, Results<(outs AnyType)>; 1231def TestInvalidOp : TEST_Op<"invalid", [Terminator]>, 1232 Arguments<(ins Variadic<AnyType>)>; 1233def TestTypeProducerOp : TEST_Op<"type_producer">, 1234 Results<(outs AnyType)>; 1235def TestTypeConsumerOp : TEST_Op<"type_consumer">, 1236 Arguments<(ins AnyType)>; 1237def TestValidOp : TEST_Op<"valid", [Terminator]>, 1238 Arguments<(ins Variadic<AnyType>)>; 1239 1240def TestMergeBlocksOp : TEST_Op<"merge_blocks"> { 1241 let summary = "merge_blocks operation"; 1242 let description = [{ 1243 Test op with multiple blocks that are merged with Dialect Conversion" 1244 }]; 1245 1246 let regions = (region AnyRegion:$body); 1247 let results = (outs Variadic<AnyType>:$result); 1248} 1249 1250//===----------------------------------------------------------------------===// 1251// Test parser. 1252//===----------------------------------------------------------------------===// 1253 1254def WrappedKeywordOp : TEST_Op<"wrapped_keyword"> { 1255 let arguments = (ins StrAttr:$keyword); 1256 let parser = [{ return ::parse$cppClass(parser, result); }]; 1257 let printer = [{ return ::print(p, *this); }]; 1258} 1259 1260//===----------------------------------------------------------------------===// 1261// Test region argument list parsing. 1262 1263def IsolatedRegionOp : TEST_Op<"isolated_region", [IsolatedFromAbove]> { 1264 let summary = "isolated region operation"; 1265 let description = [{ 1266 Test op with an isolated region, to test passthrough region arguments. Each 1267 argument is of index type. 1268 }]; 1269 1270 let arguments = (ins Index); 1271 let regions = (region SizedRegion<1>:$region); 1272 let parser = [{ return ::parse$cppClass(parser, result); }]; 1273 let printer = [{ return ::print(p, *this); }]; 1274} 1275 1276def SSACFGRegionOp : TEST_Op<"ssacfg_region", [ 1277 DeclareOpInterfaceMethods<RegionKindInterface>]> { 1278 let summary = "operation with an SSACFG region"; 1279 let description = [{ 1280 Test op that defines an SSACFG region. 1281 }]; 1282 1283 let regions = (region VariadicRegion<AnyRegion>:$regions); 1284 let arguments = (ins Variadic<AnyType>); 1285 let results = (outs Variadic<AnyType>); 1286} 1287 1288def GraphRegionOp : TEST_Op<"graph_region", [ 1289 DeclareOpInterfaceMethods<RegionKindInterface>]> { 1290 let summary = "operation with a graph region"; 1291 let description = [{ 1292 Test op that defines a graph region. 1293 }]; 1294 1295 let regions = (region AnyRegion:$region); 1296 let parser = [{ return ::parse$cppClass(parser, result); }]; 1297 let printer = [{ return ::print(p, *this); }]; 1298} 1299 1300def AffineScopeOp : TEST_Op<"affine_scope", [AffineScope]> { 1301 let summary = "affine scope operation"; 1302 let description = [{ 1303 Test op that defines a new affine scope. 1304 }]; 1305 1306 let regions = (region SizedRegion<1>:$region); 1307 let parser = [{ return ::parse$cppClass(parser, result); }]; 1308 let printer = [{ return ::print(p, *this); }]; 1309} 1310 1311def WrappingRegionOp : TEST_Op<"wrapping_region", 1312 [SingleBlockImplicitTerminator<"TestReturnOp">]> { 1313 let summary = "wrapping region operation"; 1314 let description = [{ 1315 Test op wrapping another op in a region, to test calling 1316 parseGenericOperation from the custom parser. 1317 }]; 1318 1319 let results = (outs Variadic<AnyType>); 1320 let regions = (region SizedRegion<1>:$region); 1321 let parser = [{ return ::parse$cppClass(parser, result); }]; 1322 let printer = [{ return ::print(p, *this); }]; 1323} 1324 1325def PolyForOp : TEST_Op<"polyfor"> 1326{ 1327 let summary = "polyfor operation"; 1328 let description = [{ 1329 Test op with multiple region arguments, each argument of index type. 1330 }]; 1331 1332 let regions = (region SizedRegion<1>:$region); 1333 let parser = [{ return ::parse$cppClass(parser, result); }]; 1334} 1335 1336//===----------------------------------------------------------------------===// 1337// Test OpAsmInterface. 1338 1339def AsmInterfaceOp : TEST_Op<"asm_interface_op"> { 1340 let results = (outs AnyType:$first, Variadic<AnyType>:$middle_results, 1341 AnyType); 1342} 1343 1344def AsmDialectInterfaceOp : TEST_Op<"asm_dialect_interface_op"> { 1345 let results = (outs AnyType); 1346} 1347 1348//===----------------------------------------------------------------------===// 1349// Test Op Asm Format 1350//===----------------------------------------------------------------------===// 1351 1352def FormatLiteralOp : TEST_Op<"format_literal_op"> { 1353 let assemblyFormat = [{ 1354 `keyword_$.` `->` `:` `,` `=` `<` `>` `(` `)` `[` `]` attr-dict 1355 }]; 1356} 1357 1358// Test that we elide attributes that are within the syntax. 1359def FormatAttrOp : TEST_Op<"format_attr_op"> { 1360 let arguments = (ins I64Attr:$attr); 1361 let assemblyFormat = "$attr attr-dict"; 1362} 1363 1364// Test that we elide optional attributes that are within the syntax. 1365def FormatOptAttrAOp : TEST_Op<"format_opt_attr_op_a"> { 1366 let arguments = (ins OptionalAttr<I64Attr>:$opt_attr); 1367 let assemblyFormat = "(`(` $opt_attr^ `)` )? attr-dict"; 1368} 1369def FormatOptAttrBOp : TEST_Op<"format_opt_attr_op_b"> { 1370 let arguments = (ins OptionalAttr<I64Attr>:$opt_attr); 1371 let assemblyFormat = "($opt_attr^)? attr-dict"; 1372} 1373 1374// Test that we format symbol name attributes properly. 1375def FormatSymbolNameAttrOp : TEST_Op<"format_symbol_name_attr_op"> { 1376 let arguments = (ins SymbolNameAttr:$attr); 1377 let assemblyFormat = "$attr attr-dict"; 1378} 1379 1380// Test that we format optional symbol name attributes properly. 1381def FormatOptSymbolNameAttrOp : TEST_Op<"format_opt_symbol_name_attr_op"> { 1382 let arguments = (ins OptionalAttr<SymbolNameAttr>:$opt_attr); 1383 let assemblyFormat = "($opt_attr^)? attr-dict"; 1384} 1385 1386// Test that we elide attributes that are within the syntax. 1387def FormatAttrDictWithKeywordOp : TEST_Op<"format_attr_dict_w_keyword"> { 1388 let arguments = (ins I64Attr:$attr, OptionalAttr<I64Attr>:$opt_attr); 1389 let assemblyFormat = "attr-dict-with-keyword"; 1390} 1391 1392// Test that we don't need to provide types in the format if they are buildable. 1393def FormatBuildableTypeOp : TEST_Op<"format_buildable_type_op"> { 1394 let arguments = (ins I64:$buildable); 1395 let results = (outs I64:$buildable_res); 1396 let assemblyFormat = "$buildable attr-dict"; 1397} 1398 1399// Test various mixings of region formatting. 1400class FormatRegionBase<string suffix, string fmt> 1401 : TEST_Op<"format_region_" # suffix # "_op"> { 1402 let regions = (region AnyRegion:$region); 1403 let assemblyFormat = fmt; 1404} 1405def FormatRegionAOp : FormatRegionBase<"a", [{ 1406 regions attr-dict 1407}]>; 1408def FormatRegionBOp : FormatRegionBase<"b", [{ 1409 $region attr-dict 1410}]>; 1411def FormatRegionCOp : FormatRegionBase<"c", [{ 1412 (`region` $region^)? attr-dict 1413}]>; 1414class FormatVariadicRegionBase<string suffix, string fmt> 1415 : TEST_Op<"format_variadic_region_" # suffix # "_op"> { 1416 let regions = (region VariadicRegion<AnyRegion>:$regions); 1417 let assemblyFormat = fmt; 1418} 1419def FormatVariadicRegionAOp : FormatVariadicRegionBase<"a", [{ 1420 $regions attr-dict 1421}]>; 1422def FormatVariadicRegionBOp : FormatVariadicRegionBase<"b", [{ 1423 ($regions^ `found_regions`)? attr-dict 1424}]>; 1425class FormatRegionImplicitTerminatorBase<string suffix, string fmt> 1426 : TEST_Op<"format_implicit_terminator_region_" # suffix # "_op", 1427 [SingleBlockImplicitTerminator<"TestReturnOp">]> { 1428 let regions = (region AnyRegion:$region); 1429 let assemblyFormat = fmt; 1430} 1431def FormatFormatRegionImplicitTerminatorAOp 1432 : FormatRegionImplicitTerminatorBase<"a", [{ 1433 $region attr-dict 1434}]>; 1435 1436// Test various mixings of result type formatting. 1437class FormatResultBase<string suffix, string fmt> 1438 : TEST_Op<"format_result_" # suffix # "_op"> { 1439 let results = (outs I64:$buildable_res, AnyMemRef:$result); 1440 let assemblyFormat = fmt; 1441} 1442def FormatResultAOp : FormatResultBase<"a", [{ 1443 type($result) attr-dict 1444}]>; 1445def FormatResultBOp : FormatResultBase<"b", [{ 1446 type(results) attr-dict 1447}]>; 1448def FormatResultCOp : FormatResultBase<"c", [{ 1449 functional-type($buildable_res, $result) attr-dict 1450}]>; 1451 1452// Test various mixings of operand type formatting. 1453class FormatOperandBase<string suffix, string fmt> 1454 : TEST_Op<"format_operand_" # suffix # "_op"> { 1455 let arguments = (ins I64:$buildable, AnyMemRef:$operand); 1456 let assemblyFormat = fmt; 1457} 1458 1459def FormatOperandAOp : FormatOperandBase<"a", [{ 1460 operands `:` type(operands) attr-dict 1461}]>; 1462def FormatOperandBOp : FormatOperandBase<"b", [{ 1463 operands `:` type($operand) attr-dict 1464}]>; 1465def FormatOperandCOp : FormatOperandBase<"c", [{ 1466 $buildable `,` $operand `:` type(operands) attr-dict 1467}]>; 1468def FormatOperandDOp : FormatOperandBase<"d", [{ 1469 $buildable `,` $operand `:` type($operand) attr-dict 1470}]>; 1471def FormatOperandEOp : FormatOperandBase<"e", [{ 1472 $buildable `,` $operand `:` type($buildable) `,` type($operand) attr-dict 1473}]>; 1474 1475def FormatSuccessorAOp : TEST_Op<"format_successor_a_op", [Terminator]> { 1476 let successors = (successor VariadicSuccessor<AnySuccessor>:$targets); 1477 let assemblyFormat = "$targets attr-dict"; 1478} 1479 1480// Test various mixings of optional operand and result type formatting. 1481class FormatOptionalOperandResultOpBase<string suffix, string fmt> 1482 : TEST_Op<"format_optional_operand_result_" # suffix # "_op", 1483 [AttrSizedOperandSegments]> { 1484 let arguments = (ins Optional<I64>:$optional, Variadic<I64>:$variadic); 1485 let results = (outs Optional<I64>:$optional_res); 1486 let assemblyFormat = fmt; 1487} 1488 1489def FormatOptionalOperandResultAOp : FormatOptionalOperandResultOpBase<"a", [{ 1490 `(` $optional `:` type($optional) `)` `:` type($optional_res) 1491 (`[` $variadic^ `]`)? attr-dict 1492}]>; 1493 1494def FormatOptionalOperandResultBOp : FormatOptionalOperandResultOpBase<"b", [{ 1495 (`(` $optional^ `:` type($optional) `)`)? `:` type($optional_res) 1496 (`[` $variadic^ `]`)? attr-dict 1497}]>; 1498 1499def FormatTwoVariadicOperandsNoBuildableTypeOp 1500 : TEST_Op<"format_two_variadic_operands_no_buildable_type_op", 1501 [AttrSizedOperandSegments]> { 1502 let arguments = (ins Variadic<AnyType>:$a, 1503 Variadic<AnyType>:$b); 1504 let assemblyFormat = [{ 1505 `(` $a `:` type($a) `)` `->` `(` $b `:` type($b) `)` attr-dict 1506 }]; 1507} 1508 1509def FormatInferVariadicTypeFromNonVariadic 1510 : TEST_Op<"format_infer_variadic_type_from_non_variadic", 1511 [SameOperandsAndResultType]> { 1512 let arguments = (ins Variadic<AnyType>:$operands); 1513 let results = (outs AnyType:$result); 1514 let assemblyFormat = "$operands attr-dict `:` type($result)"; 1515} 1516 1517def FormatOptionalUnitAttr : TEST_Op<"format_optional_unit_attribute"> { 1518 let arguments = (ins UnitAttr:$is_optional); 1519 let assemblyFormat = "(`is_optional` $is_optional^)? attr-dict"; 1520} 1521 1522def FormatOptionalUnitAttrNoElide 1523 : TEST_Op<"format_optional_unit_attribute_no_elide"> { 1524 let arguments = (ins UnitAttr:$is_optional); 1525 let assemblyFormat = "($is_optional^)? attr-dict"; 1526} 1527 1528//===----------------------------------------------------------------------===// 1529// Custom Directives 1530 1531def FormatCustomDirectiveOperands 1532 : TEST_Op<"format_custom_directive_operands", [AttrSizedOperandSegments]> { 1533 let arguments = (ins I64:$operand, Optional<I64>:$optOperand, 1534 Variadic<I64>:$varOperands); 1535 let assemblyFormat = [{ 1536 custom<CustomDirectiveOperands>( 1537 $operand, $optOperand, $varOperands 1538 ) 1539 attr-dict 1540 }]; 1541} 1542 1543def FormatCustomDirectiveOperandsAndTypes 1544 : TEST_Op<"format_custom_directive_operands_and_types", 1545 [AttrSizedOperandSegments]> { 1546 let arguments = (ins AnyType:$operand, Optional<AnyType>:$optOperand, 1547 Variadic<AnyType>:$varOperands); 1548 let assemblyFormat = [{ 1549 custom<CustomDirectiveOperandsAndTypes>( 1550 $operand, $optOperand, $varOperands, 1551 type($operand), type($optOperand), type($varOperands) 1552 ) 1553 attr-dict 1554 }]; 1555} 1556 1557def FormatCustomDirectiveRegions : TEST_Op<"format_custom_directive_regions"> { 1558 let regions = (region AnyRegion:$region, VariadicRegion<AnyRegion>:$regions); 1559 let assemblyFormat = [{ 1560 custom<CustomDirectiveRegions>( 1561 $region, $regions 1562 ) 1563 attr-dict 1564 }]; 1565} 1566 1567def FormatCustomDirectiveResults 1568 : TEST_Op<"format_custom_directive_results", [AttrSizedResultSegments]> { 1569 let results = (outs AnyType:$result, Optional<AnyType>:$optResult, 1570 Variadic<AnyType>:$varResults); 1571 let assemblyFormat = [{ 1572 custom<CustomDirectiveResults>( 1573 type($result), type($optResult), type($varResults) 1574 ) 1575 attr-dict 1576 }]; 1577} 1578 1579def FormatCustomDirectiveResultsWithTypeRefs 1580 : TEST_Op<"format_custom_directive_results_with_type_refs", 1581 [AttrSizedResultSegments]> { 1582 let results = (outs AnyType:$result, Optional<AnyType>:$optResult, 1583 Variadic<AnyType>:$varResults); 1584 let assemblyFormat = [{ 1585 custom<CustomDirectiveResults>( 1586 type($result), type($optResult), type($varResults) 1587 ) 1588 custom<CustomDirectiveWithTypeRefs>( 1589 type_ref($result), type_ref($optResult), type_ref($varResults) 1590 ) 1591 attr-dict 1592 }]; 1593} 1594 1595def FormatCustomDirectiveSuccessors 1596 : TEST_Op<"format_custom_directive_successors", [Terminator]> { 1597 let successors = (successor AnySuccessor:$successor, 1598 VariadicSuccessor<AnySuccessor>:$successors); 1599 let assemblyFormat = [{ 1600 custom<CustomDirectiveSuccessors>( 1601 $successor, $successors 1602 ) 1603 attr-dict 1604 }]; 1605} 1606 1607def FormatCustomDirectiveAttributes 1608 : TEST_Op<"format_custom_directive_attributes"> { 1609 let arguments = (ins I64Attr:$attr, OptionalAttr<I64Attr>:$optAttr); 1610 let assemblyFormat = [{ 1611 custom<CustomDirectiveAttributes>( 1612 $attr, $optAttr 1613 ) 1614 attr-dict 1615 }]; 1616} 1617 1618//===----------------------------------------------------------------------===// 1619// AllTypesMatch type inference 1620 1621def FormatAllTypesMatchVarOp : TEST_Op<"format_all_types_match_var", [ 1622 AllTypesMatch<["value1", "value2", "result"]> 1623 ]> { 1624 let arguments = (ins AnyType:$value1, AnyType:$value2); 1625 let results = (outs AnyType:$result); 1626 let assemblyFormat = "attr-dict $value1 `,` $value2 `:` type($value1)"; 1627} 1628 1629def FormatAllTypesMatchAttrOp : TEST_Op<"format_all_types_match_attr", [ 1630 AllTypesMatch<["value1", "value2", "result"]> 1631 ]> { 1632 let arguments = (ins AnyAttr:$value1, AnyType:$value2); 1633 let results = (outs AnyType:$result); 1634 let assemblyFormat = "attr-dict $value1 `,` $value2"; 1635} 1636 1637//===----------------------------------------------------------------------===// 1638// TypesMatchWith type inference 1639 1640def FormatTypesMatchVarOp : TEST_Op<"format_types_match_var", [ 1641 TypesMatchWith<"result type matches operand", "value", "result", "$_self"> 1642 ]> { 1643 let arguments = (ins AnyType:$value); 1644 let results = (outs AnyType:$result); 1645 let assemblyFormat = "attr-dict $value `:` type($value)"; 1646} 1647 1648def FormatTypesMatchAttrOp : TEST_Op<"format_types_match_attr", [ 1649 TypesMatchWith<"result type matches constant", "value", "result", "$_self"> 1650 ]> { 1651 let arguments = (ins AnyAttr:$value); 1652 let results = (outs AnyType:$result); 1653 let assemblyFormat = "attr-dict $value"; 1654} 1655 1656//===----------------------------------------------------------------------===// 1657// Test SideEffects 1658//===----------------------------------------------------------------------===// 1659 1660def SideEffectOp : TEST_Op<"side_effect_op", 1661 [DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> { 1662 let results = (outs AnyType:$result); 1663} 1664 1665//===----------------------------------------------------------------------===// 1666// Test RegionBranchOpInterface 1667//===----------------------------------------------------------------------===// 1668 1669def RegionIfYieldOp : TEST_Op<"region_if_yield", 1670 [NoSideEffect, ReturnLike, Terminator]> { 1671 let arguments = (ins Variadic<AnyType>:$results); 1672 let assemblyFormat = [{ 1673 $results `:` type($results) attr-dict 1674 }]; 1675} 1676 1677def RegionIfOp : TEST_Op<"region_if", 1678 [DeclareOpInterfaceMethods<RegionBranchOpInterface>, 1679 SingleBlockImplicitTerminator<"RegionIfYieldOp">, 1680 RecursiveSideEffects]> { 1681 let description =[{ 1682 Represents an abstract if-then-else-join pattern. In this context, the then 1683 and else regions jump to the join region, which finally returns to its 1684 parent op. 1685 }]; 1686 1687 let printer = [{ return ::print(p, *this); }]; 1688 let parser = [{ return ::parseRegionIfOp(parser, result); }]; 1689 let arguments = (ins Variadic<AnyType>); 1690 let results = (outs Variadic<AnyType>:$results); 1691 let regions = (region SizedRegion<1>:$thenRegion, 1692 AnyRegion:$elseRegion, 1693 AnyRegion:$joinRegion); 1694 let extraClassDeclaration = [{ 1695 Block::BlockArgListType getThenArgs() { 1696 return getBody(0)->getArguments(); 1697 } 1698 Block::BlockArgListType getElseArgs() { 1699 return getBody(1)->getArguments(); 1700 } 1701 Block::BlockArgListType getJoinArgs() { 1702 return getBody(2)->getArguments(); 1703 } 1704 OperandRange getSuccessorEntryOperands(unsigned index); 1705 }]; 1706} 1707 1708//===----------------------------------------------------------------------===// 1709// Test TableGen generated build() methods 1710//===----------------------------------------------------------------------===// 1711 1712def TableGenConstant : TEST_Op<"tblgen_constant"> { 1713 let results = (outs AnyType); 1714} 1715 1716// No variadic args or results. 1717def TableGenBuildOp0 : TEST_Op<"tblgen_build_0"> { 1718 let arguments = (ins AnyType:$value); 1719 let results = (outs AnyType:$result); 1720} 1721 1722// Sigle variadic arg and single variadic results. 1723def TableGenBuildOp1 : TEST_Op<"tblgen_build_1"> { 1724 let arguments = (ins Variadic<AnyType>:$inputs); 1725 let results = (outs Variadic<AnyType>:$results); 1726} 1727 1728// Single variadic arg and non-variadic results. 1729def TableGenBuildOp2 : TEST_Op<"tblgen_build_2"> { 1730 let arguments = (ins Variadic<AnyType>:$inputs); 1731 let results = (outs AnyType:$result); 1732} 1733 1734// Single variadic arg and multiple variadic results. 1735def TableGenBuildOp3 : TEST_Op<"tblgen_build_3", [SameVariadicResultSize]> { 1736 let arguments = (ins Variadic<AnyType>:$inputs); 1737 let results = (outs Variadic<AnyType>:$resultA, Variadic<AnyType>:$resultB); 1738} 1739 1740// Single variadic arg, non variadic results, with SameOperandsAndResultType. 1741// Tests suppression of ambiguous build methods for operations with 1742// SameOperandsAndResultType trait. 1743def TableGenBuildOp4 : TEST_Op<"tblgen_build_4", [SameOperandsAndResultType]> { 1744 let arguments = (ins Variadic<AnyType>:$inputs); 1745 let results = (outs AnyType:$result); 1746} 1747 1748// Single variadic arg with SameOperandsAndResultType and InferTypeOpInterface. 1749// Tests suppression of ambiguous build methods for operations with 1750// SameOperandsAndResultType and InferTypeOpInterface. 1751def TableGenBuildOp5 : TEST_Op<"tblgen_build_5", 1752 [SameOperandsAndResultType, InferTypeOpInterface]> { 1753 let arguments = (ins Variadic<AnyType>:$inputs); 1754 let results = (outs AnyType:$result); 1755 1756 let extraClassDeclaration = [{ 1757 static LogicalResult inferReturnTypes(MLIRContext *, 1758 Optional<Location> location, ValueRange operands, 1759 DictionaryAttr attributes, RegionRange regions, 1760 SmallVectorImpl<Type> &inferredReturnTypes) { 1761 inferredReturnTypes.assign({operands[0].getType()}); 1762 return success(); 1763 } 1764 }]; 1765} 1766 1767//===----------------------------------------------------------------------===// 1768// Test BufferPlacement 1769//===----------------------------------------------------------------------===// 1770 1771def GetTupleElementOp: TEST_Op<"get_tuple_element"> { 1772 let description = [{ 1773 Test op that returns a specified element of the tuple. 1774 }]; 1775 1776 let arguments = (ins 1777 TupleOf<[AnyType]>, 1778 I32Attr:$index 1779 ); 1780 let results = (outs AnyType); 1781} 1782 1783def MakeTupleOp: TEST_Op<"make_tuple"> { 1784 let description = [{ 1785 Test op that creates a tuple value from a list of values. 1786 }]; 1787 1788 let arguments = (ins 1789 Variadic<AnyType>:$inputs 1790 ); 1791 let results = (outs TupleOf<[AnyType]>); 1792} 1793 1794#endif // TEST_OPS 1795