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 802def TestOpConstant : TEST_Op<"constant", [ConstantLike, NoSideEffect]> { 803 let arguments = (ins AnyAttr:$value); 804 let results = (outs AnyType); 805 let extraClassDeclaration = [{ 806 Attribute getValue() { return getAttr("value"); } 807 }]; 808 809 let hasFolder = 1; 810} 811 812def OpR : TEST_Op<"op_r">, Arguments<(ins AnyInteger, AnyInteger)>, Results<(outs AnyInteger)>; 813def OpS : TEST_Op<"op_s">, Arguments<(ins AnyInteger, AnyAttr:$value)>, Results<(outs AnyInteger)>; 814 815def : Pat<(OpR $input1, (ConstantLikeMatcher I32Attr:$input2)), 816 (OpS:$unused $input1, $input2)>; 817 818// Op for testing trivial removal via folding of op with inner ops and no uses. 819def TestOpWithRegionFoldNoSideEffect : TEST_Op< 820 "op_with_region_fold_no_side_effect", [NoSideEffect]> { 821 let regions = (region SizedRegion<1>:$region); 822} 823 824// Op for testing folding of outer op with inner ops. 825def TestOpWithRegionFold : TEST_Op<"op_with_region_fold"> { 826 let arguments = (ins I32:$operand); 827 let results = (outs I32); 828 let regions = (region SizedRegion<1>:$region); 829 let hasFolder = 1; 830} 831 832def TestOpWithVariadicResultsAndFolder: TEST_Op<"op_with_variadic_results_and_folder"> { 833 let arguments = (ins Variadic<I32>:$operands); 834 let results = (outs Variadic<I32>); 835 let hasFolder = 1; 836} 837 838def TestCommutativeOp : TEST_Op<"op_commutative", [Commutative]> { 839 let arguments = (ins I32:$op1, I32:$op2, I32:$op3, I32:$op4); 840 let results = (outs I32); 841} 842 843def TestIdempotentTraitOp 844 : TEST_Op<"op_idempotent_trait", 845 [SameOperandsAndResultType, NoSideEffect, Idempotent]> { 846 let arguments = (ins I32:$op1); 847 let results = (outs I32); 848} 849 850def TestInvolutionTraitNoOperationFolderOp 851 : TEST_Op<"op_involution_trait_no_operation_fold", 852 [SameOperandsAndResultType, NoSideEffect, Involution]> { 853 let arguments = (ins I32:$op1); 854 let results = (outs I32); 855} 856 857def TestInvolutionTraitFailingOperationFolderOp 858 : TEST_Op<"op_involution_trait_failing_operation_fold", 859 [SameOperandsAndResultType, NoSideEffect, Involution]> { 860 let arguments = (ins I32:$op1); 861 let results = (outs I32); 862 let hasFolder = 1; 863} 864 865def TestInvolutionTraitSuccesfulOperationFolderOp 866 : TEST_Op<"op_involution_trait_succesful_operation_fold", 867 [SameOperandsAndResultType, NoSideEffect, Involution]> { 868 let arguments = (ins I32:$op1); 869 let results = (outs I32); 870 let hasFolder = 1; 871} 872 873def TestOpInPlaceFoldAnchor : TEST_Op<"op_in_place_fold_anchor"> { 874 let arguments = (ins I32); 875 let results = (outs I32); 876} 877 878def TestOpInPlaceFold : TEST_Op<"op_in_place_fold"> { 879 let arguments = (ins I32:$op, I32Attr:$attr); 880 let results = (outs I32); 881 let hasFolder = 1; 882} 883 884//===----------------------------------------------------------------------===// 885// Test Patterns (Symbol Binding) 886 887// Test symbol binding. 888def OpSymbolBindingA : TEST_Op<"symbol_binding_a", []> { 889 let arguments = (ins I32:$operand, I64Attr:$attr); 890 let results = (outs I32); 891} 892def OpSymbolBindingB : TEST_Op<"symbol_binding_b", []> { 893 let arguments = (ins I32:$operand); 894 let results = (outs I32); 895} 896def OpSymbolBindingC : TEST_Op<"symbol_binding_c", []> { 897 let arguments = (ins I32:$operand); 898 let results = (outs I32); 899 let builders = OpSymbolBindingB.builders; 900} 901def OpSymbolBindingD : TEST_Op<"symbol_binding_d", []> { 902 let arguments = (ins I32:$input1, I32:$input2, I64Attr:$attr); 903 let results = (outs I32); 904} 905def HasOneUse: Constraint<CPred<"$0.hasOneUse()">, "has one use">; 906def : Pattern< 907 // Bind to source pattern op operand/attribute/result 908 (OpSymbolBindingA:$res_a $operand, $attr), [ 909 // Bind to auxiliary op result 910 (OpSymbolBindingC:$res_c (OpSymbolBindingB:$res_b $operand)), 911 912 // Use bound symbols in resultant ops 913 (OpSymbolBindingD $res_b, $res_c, $attr)], 914 // Use bound symbols in additional constraints 915 [(HasOneUse $res_a)]>; 916 917def OpSymbolBindingNoResult : TEST_Op<"symbol_binding_no_result", []> { 918 let arguments = (ins I32:$operand); 919} 920 921// Test that we can bind to an op without results and reference it later. 922def : Pat<(OpSymbolBindingNoResult:$op $operand), 923 (NativeCodeCall<"handleNoResultOp($_builder, $0)"> $op)>; 924 925//===----------------------------------------------------------------------===// 926// Test Patterns (Attributes) 927 928// Test matching against op attributes. 929def OpAttrMatch1 : TEST_Op<"match_op_attribute1"> { 930 let arguments = (ins 931 I32Attr:$required_attr, 932 OptionalAttr<I32Attr>:$optional_attr, 933 DefaultValuedAttr<I32Attr, "42">:$default_valued_attr, 934 I32Attr:$more_attr 935 ); 936 let results = (outs I32); 937} 938def OpAttrMatch2 : TEST_Op<"match_op_attribute2"> { 939 let arguments = OpAttrMatch1.arguments; 940 let results = (outs I32); 941} 942def MoreConstraint : AttrConstraint< 943 CPred<"$_self.cast<IntegerAttr>().getInt() == 4">, "more constraint">; 944def : Pat<(OpAttrMatch1 $required, $optional, $default_valued, 945 MoreConstraint:$more), 946 (OpAttrMatch2 $required, $optional, $default_valued, $more)>; 947 948// Test unit attrs. 949def OpAttrMatch3 : TEST_Op<"match_op_attribute3"> { 950 let arguments = (ins UnitAttr:$attr); 951 let results = (outs I32); 952} 953def OpAttrMatch4 : TEST_Op<"match_op_attribute4"> { 954 let arguments = (ins UnitAttr:$attr1, UnitAttr:$attr2); 955 let results = (outs I32); 956} 957def : Pat<(OpAttrMatch3 $attr), (OpAttrMatch4 ConstUnitAttr, $attr)>; 958 959// Test with constant attr. 960def OpC : TEST_Op<"op_c">, Arguments<(ins I32)>, Results<(outs I32)>; 961def : Pat<(OpC $input), (OpB $input, ConstantAttr<I32Attr, "17">:$attr)>; 962 963// Test string enum attribute in rewrites. 964def : Pat<(StrEnumAttrOp StrCaseA), (StrEnumAttrOp StrCaseB)>; 965// Test integer enum attribute in rewrites. 966def : Pat<(I32EnumAttrOp I32Case5), (I32EnumAttrOp I32Case10)>; 967def : Pat<(I64EnumAttrOp I64Case5), (I64EnumAttrOp I64Case10)>; 968 969//===----------------------------------------------------------------------===// 970// Test Patterns (Multi-result Ops) 971 972def MultiResultOpKind1: I64EnumAttrCase<"kind1", 1>; 973def MultiResultOpKind2: I64EnumAttrCase<"kind2", 2>; 974def MultiResultOpKind3: I64EnumAttrCase<"kind3", 3>; 975def MultiResultOpKind4: I64EnumAttrCase<"kind4", 4>; 976def MultiResultOpKind5: I64EnumAttrCase<"kind5", 5>; 977def MultiResultOpKind6: I64EnumAttrCase<"kind6", 6>; 978 979def MultiResultOpEnum: I64EnumAttr< 980 "MultiResultOpEnum", "Multi-result op kinds", [ 981 MultiResultOpKind1, MultiResultOpKind2, MultiResultOpKind3, 982 MultiResultOpKind4, MultiResultOpKind5, MultiResultOpKind6 983 ]>; 984 985def ThreeResultOp : TEST_Op<"three_result"> { 986 let arguments = (ins MultiResultOpEnum:$kind); 987 let results = (outs I32:$result1, F32:$result2, F32:$result3); 988} 989 990def AnotherThreeResultOp : TEST_Op<"another_three_result"> { 991 let arguments = (ins MultiResultOpEnum:$kind); 992 let results = (outs I32:$result1, F32:$result2, F32:$result3); 993} 994 995def TwoResultOp : TEST_Op<"two_result"> { 996 let arguments = (ins MultiResultOpEnum:$kind); 997 let results = (outs I32:$result1, F32:$result2); 998} 999 1000def AnotherTwoResultOp : TEST_Op<"another_two_result"> { 1001 let arguments = (ins MultiResultOpEnum:$kind); 1002 let results = (outs F32:$result1, F32:$result2); 1003} 1004 1005def OneResultOp1 : TEST_Op<"one_result1"> { 1006 let arguments = (ins MultiResultOpEnum:$kind); 1007 let results = (outs F32:$result1); 1008} 1009 1010def OneResultOp2 : TEST_Op<"one_result2"> { 1011 let arguments = (ins MultiResultOpEnum:$kind); 1012 let results = (outs I32:$result1); 1013} 1014 1015def OneResultOp3 : TEST_Op<"one_result3"> { 1016 let arguments = (ins F32); 1017 let results = (outs I32:$result1); 1018} 1019 1020// Test using multi-result op as a whole 1021def : Pat<(ThreeResultOp MultiResultOpKind1), 1022 (AnotherThreeResultOp MultiResultOpKind1)>; 1023 1024// Test using multi-result op as a whole for partial replacement 1025def : Pattern<(ThreeResultOp MultiResultOpKind2), 1026 [(TwoResultOp MultiResultOpKind2), 1027 (OneResultOp1 MultiResultOpKind2)]>; 1028def : Pattern<(ThreeResultOp MultiResultOpKind3), 1029 [(OneResultOp2 MultiResultOpKind3), 1030 (AnotherTwoResultOp MultiResultOpKind3)]>; 1031 1032// Test using results separately in a multi-result op 1033def : Pattern<(ThreeResultOp MultiResultOpKind4), 1034 [(TwoResultOp:$res1__0 MultiResultOpKind4), 1035 (OneResultOp1 MultiResultOpKind4), 1036 (TwoResultOp:$res2__1 MultiResultOpKind4)]>; 1037 1038// Test referencing a single value in the value pack 1039// This rule only matches TwoResultOp if its second result has no use. 1040def : Pattern<(TwoResultOp:$res MultiResultOpKind5), 1041 [(OneResultOp2 MultiResultOpKind5), 1042 (OneResultOp1 MultiResultOpKind5)], 1043 [(HasNoUseOf:$res__1)]>; 1044 1045// Test using auxiliary ops for replacing multi-result op 1046def : Pattern< 1047 (ThreeResultOp MultiResultOpKind6), [ 1048 // Auxiliary op generated to help building the final result but not 1049 // directly used to replace the source op's results. 1050 (TwoResultOp:$interm MultiResultOpKind6), 1051 1052 (OneResultOp3 $interm__1), 1053 (AnotherTwoResultOp MultiResultOpKind6) 1054 ]>; 1055 1056//===----------------------------------------------------------------------===// 1057// Test Patterns (Variadic Ops) 1058 1059def OneVResOneVOperandOp1 : TEST_Op<"one_variadic_out_one_variadic_in1"> { 1060 let arguments = (ins Variadic<I32>); 1061 let results = (outs Variadic<I32>); 1062} 1063def OneVResOneVOperandOp2 : TEST_Op<"one_variadic_out_one_variadic_in2"> { 1064 let arguments = (ins Variadic<I32>); 1065 let results = (outs Variadic<I32>); 1066} 1067 1068// Rewrite an op with one variadic operand and one variadic result to 1069// another similar op. 1070def : Pat<(OneVResOneVOperandOp1 $inputs), (OneVResOneVOperandOp2 $inputs)>; 1071 1072def MixedVOperandOp1 : TEST_Op<"mixed_variadic_in1", 1073 [SameVariadicOperandSize]> { 1074 let arguments = (ins 1075 Variadic<I32>:$input1, 1076 F32:$input2, 1077 Variadic<I32>:$input3 1078 ); 1079} 1080 1081def MixedVOperandOp2 : TEST_Op<"mixed_variadic_in2", 1082 [SameVariadicOperandSize]> { 1083 let arguments = (ins 1084 Variadic<I32>:$input1, 1085 F32:$input2, 1086 Variadic<I32>:$input3 1087 ); 1088} 1089 1090// Rewrite an op with both variadic operands and normal operands. 1091def : Pat<(MixedVOperandOp1 $input1, $input2, $input3), 1092 (MixedVOperandOp2 $input1, $input2, $input3)>; 1093 1094def MixedVResultOp1 : TEST_Op<"mixed_variadic_out1", [SameVariadicResultSize]> { 1095 let results = (outs 1096 Variadic<I32>:$output1, 1097 F32:$output2, 1098 Variadic<I32>:$output3 1099 ); 1100} 1101 1102def MixedVResultOp2 : TEST_Op<"mixed_variadic_out2", [SameVariadicResultSize]> { 1103 let results = (outs 1104 Variadic<I32>:$output1, 1105 F32:$output2, 1106 Variadic<I32>:$output3 1107 ); 1108} 1109 1110// Rewrite an op with both variadic results and normal results. 1111// Note that because we are generating the op with a top-level result pattern, 1112// we are able to deduce the correct result types for the generated op using 1113// the information from the matched root op. 1114def : Pat<(MixedVResultOp1), (MixedVResultOp2)>; 1115 1116def OneI32ResultOp : TEST_Op<"one_i32_out"> { 1117 let results = (outs I32); 1118} 1119 1120def MixedVOperandOp3 : TEST_Op<"mixed_variadic_in3", 1121 [SameVariadicOperandSize]> { 1122 let arguments = (ins 1123 I32:$input1, 1124 Variadic<I32>:$input2, 1125 Variadic<I32>:$input3, 1126 I32Attr:$count 1127 ); 1128 1129 let results = (outs I32); 1130} 1131 1132def MixedVResultOp3 : TEST_Op<"mixed_variadic_out3", 1133 [SameVariadicResultSize]> { 1134 let arguments = (ins I32Attr:$count); 1135 1136 let results = (outs 1137 I32:$output1, 1138 Variadic<I32>:$output2, 1139 Variadic<I32>:$output3 1140 ); 1141 1142 // We will use this op in a nested result pattern, where we cannot deduce the 1143 // result type. So need to provide a builder not requiring result types. 1144 let builders = [ 1145 OpBuilder< 1146 "IntegerAttr count", 1147 [{ 1148 auto i32Type = $_builder.getIntegerType(32); 1149 $_state.addTypes(i32Type); // $output1 1150 SmallVector<Type, 4> types(count.getInt(), i32Type); 1151 $_state.addTypes(types); // $output2 1152 $_state.addTypes(types); // $output3 1153 $_state.addAttribute("count", count); 1154 }]> 1155 ]; 1156} 1157 1158// Generates an op with variadic results using nested pattern. 1159def : Pat<(OneI32ResultOp), 1160 (MixedVOperandOp3 1161 (MixedVResultOp3:$results__0 ConstantAttr<I32Attr, "2">), 1162 (replaceWithValue $results__1), 1163 (replaceWithValue $results__2), 1164 ConstantAttr<I32Attr, "2">)>; 1165 1166//===----------------------------------------------------------------------===// 1167// Test Patterns (Location) 1168 1169// Test that we can specify locations for generated ops. 1170def : Pat<(TestLocationSrcOp:$res1 1171 (TestLocationSrcOp:$res2 1172 (TestLocationSrcOp:$res3 $input))), 1173 (TestLocationDstOp 1174 (TestLocationDstOp 1175 (TestLocationDstOp $input, (location $res1)), 1176 (location "named")), 1177 (location "fused", $res2, $res3))>; 1178 1179//===----------------------------------------------------------------------===// 1180// Test Legalization 1181//===----------------------------------------------------------------------===// 1182 1183def Test_LegalizerEnum_Success : StrEnumAttrCase<"Success">; 1184def Test_LegalizerEnum_Failure : StrEnumAttrCase<"Failure">; 1185 1186def Test_LegalizerEnum : StrEnumAttr<"Success", "Failure", 1187 [Test_LegalizerEnum_Success, Test_LegalizerEnum_Failure]>; 1188 1189def ILLegalOpA : TEST_Op<"illegal_op_a">, Results<(outs I32)>; 1190def ILLegalOpB : TEST_Op<"illegal_op_b">, Results<(outs I32)>; 1191def ILLegalOpC : TEST_Op<"illegal_op_c">, Results<(outs I32)>; 1192def ILLegalOpD : TEST_Op<"illegal_op_d">, Results<(outs I32)>; 1193def ILLegalOpE : TEST_Op<"illegal_op_e">, Results<(outs I32)>; 1194def ILLegalOpF : TEST_Op<"illegal_op_f">, Results<(outs I32)>; 1195def LegalOpA : TEST_Op<"legal_op_a">, 1196 Arguments<(ins Test_LegalizerEnum:$status)>, Results<(outs I32)>; 1197def LegalOpB : TEST_Op<"legal_op_b">, Results<(outs I32)>; 1198 1199// Check that the conversion infrastructure can properly undo the creation of 1200// operations where an operation was created before its parent, in this case, 1201// in the parent's builder. 1202def IllegalOpTerminator : TEST_Op<"illegal_op_terminator", [Terminator]>; 1203def IllegalOpWithRegion : TEST_Op<"illegal_op_with_region"> { 1204 let skipDefaultBuilders = 1; 1205 let builders = [OpBuilder<"", 1206 [{ Region *bodyRegion = $_state.addRegion(); 1207 OpBuilder::InsertionGuard g($_builder); 1208 Block *body = $_builder.createBlock(bodyRegion); 1209 $_builder.setInsertionPointToEnd(body); 1210 $_builder.create<IllegalOpTerminator>($_state.location); 1211 }]>]; 1212} 1213def IllegalOpWithRegionAnchor : TEST_Op<"illegal_op_with_region_anchor">; 1214 1215// Check that smaller pattern depths are chosen, i.e. prioritize more direct 1216// mappings. 1217def : Pat<(ILLegalOpA), (LegalOpA Test_LegalizerEnum_Success)>; 1218 1219def : Pat<(ILLegalOpA), (ILLegalOpB)>; 1220def : Pat<(ILLegalOpB), (LegalOpA Test_LegalizerEnum_Failure)>; 1221 1222// Check that the higher benefit pattern is taken for multiple legalizations 1223// with the same depth. 1224def : Pat<(ILLegalOpC), (ILLegalOpD)>; 1225def : Pat<(ILLegalOpD), (LegalOpA Test_LegalizerEnum_Failure)>; 1226 1227def : Pat<(ILLegalOpC), (ILLegalOpE), [], (addBenefit 10)>; 1228def : Pat<(ILLegalOpE), (LegalOpA Test_LegalizerEnum_Success)>; 1229 1230// Check that patterns use the most up-to-date value when being replaced. 1231def TestRewriteOp : TEST_Op<"rewrite">, 1232 Arguments<(ins AnyType)>, Results<(outs AnyType)>; 1233def : Pat<(TestRewriteOp $input), (replaceWithValue $input)>; 1234 1235// Check that patterns can specify bounded recursion when rewriting. 1236def TestRecursiveRewriteOp : TEST_Op<"recursive_rewrite"> { 1237 let arguments = (ins I64Attr:$depth); 1238 let assemblyFormat = "$depth attr-dict"; 1239} 1240 1241//===----------------------------------------------------------------------===// 1242// Test Type Legalization 1243//===----------------------------------------------------------------------===// 1244 1245def TestRegionBuilderOp : TEST_Op<"region_builder">; 1246def TestReturnOp : TEST_Op<"return", [ReturnLike, Terminator]> { 1247 let arguments = (ins Variadic<AnyType>); 1248 let builders = [ 1249 OpBuilder<"", [{ build($_builder, $_state, {}); }]> 1250 ]; 1251} 1252def TestCastOp : TEST_Op<"cast">, 1253 Arguments<(ins Variadic<AnyType>)>, Results<(outs AnyType)>; 1254def TestInvalidOp : TEST_Op<"invalid", [Terminator]>, 1255 Arguments<(ins Variadic<AnyType>)>; 1256def TestTypeProducerOp : TEST_Op<"type_producer">, 1257 Results<(outs AnyType)>; 1258def TestTypeConsumerOp : TEST_Op<"type_consumer">, 1259 Arguments<(ins AnyType)>; 1260def TestValidOp : TEST_Op<"valid", [Terminator]>, 1261 Arguments<(ins Variadic<AnyType>)>; 1262 1263def TestMergeBlocksOp : TEST_Op<"merge_blocks"> { 1264 let summary = "merge_blocks operation"; 1265 let description = [{ 1266 Test op with multiple blocks that are merged with Dialect Conversion" 1267 }]; 1268 1269 let regions = (region AnyRegion:$body); 1270 let results = (outs Variadic<AnyType>:$result); 1271} 1272 1273//===----------------------------------------------------------------------===// 1274// Test parser. 1275//===----------------------------------------------------------------------===// 1276 1277def WrappedKeywordOp : TEST_Op<"wrapped_keyword"> { 1278 let arguments = (ins StrAttr:$keyword); 1279 let parser = [{ return ::parse$cppClass(parser, result); }]; 1280 let printer = [{ return ::print(p, *this); }]; 1281} 1282 1283//===----------------------------------------------------------------------===// 1284// Test region argument list parsing. 1285 1286def IsolatedRegionOp : TEST_Op<"isolated_region", [IsolatedFromAbove]> { 1287 let summary = "isolated region operation"; 1288 let description = [{ 1289 Test op with an isolated region, to test passthrough region arguments. Each 1290 argument is of index type. 1291 }]; 1292 1293 let arguments = (ins Index); 1294 let regions = (region SizedRegion<1>:$region); 1295 let parser = [{ return ::parse$cppClass(parser, result); }]; 1296 let printer = [{ return ::print(p, *this); }]; 1297} 1298 1299def SSACFGRegionOp : TEST_Op<"ssacfg_region", [ 1300 DeclareOpInterfaceMethods<RegionKindInterface>]> { 1301 let summary = "operation with an SSACFG region"; 1302 let description = [{ 1303 Test op that defines an SSACFG region. 1304 }]; 1305 1306 let regions = (region VariadicRegion<AnyRegion>:$regions); 1307 let arguments = (ins Variadic<AnyType>); 1308 let results = (outs Variadic<AnyType>); 1309} 1310 1311def GraphRegionOp : TEST_Op<"graph_region", [ 1312 DeclareOpInterfaceMethods<RegionKindInterface>]> { 1313 let summary = "operation with a graph region"; 1314 let description = [{ 1315 Test op that defines a graph region. 1316 }]; 1317 1318 let regions = (region AnyRegion:$region); 1319 let parser = [{ return ::parse$cppClass(parser, result); }]; 1320 let printer = [{ return ::print(p, *this); }]; 1321} 1322 1323def AffineScopeOp : TEST_Op<"affine_scope", [AffineScope]> { 1324 let summary = "affine scope operation"; 1325 let description = [{ 1326 Test op that defines a new affine scope. 1327 }]; 1328 1329 let regions = (region SizedRegion<1>:$region); 1330 let parser = [{ return ::parse$cppClass(parser, result); }]; 1331 let printer = [{ return ::print(p, *this); }]; 1332} 1333 1334def WrappingRegionOp : TEST_Op<"wrapping_region", 1335 [SingleBlockImplicitTerminator<"TestReturnOp">]> { 1336 let summary = "wrapping region operation"; 1337 let description = [{ 1338 Test op wrapping another op in a region, to test calling 1339 parseGenericOperation from the custom parser. 1340 }]; 1341 1342 let results = (outs Variadic<AnyType>); 1343 let regions = (region SizedRegion<1>:$region); 1344 let parser = [{ return ::parse$cppClass(parser, result); }]; 1345 let printer = [{ return ::print(p, *this); }]; 1346} 1347 1348def PolyForOp : TEST_Op<"polyfor"> 1349{ 1350 let summary = "polyfor operation"; 1351 let description = [{ 1352 Test op with multiple region arguments, each argument of index type. 1353 }]; 1354 1355 let regions = (region SizedRegion<1>:$region); 1356 let parser = [{ return ::parse$cppClass(parser, result); }]; 1357} 1358 1359//===----------------------------------------------------------------------===// 1360// Test OpAsmInterface. 1361 1362def AsmInterfaceOp : TEST_Op<"asm_interface_op"> { 1363 let results = (outs AnyType:$first, Variadic<AnyType>:$middle_results, 1364 AnyType); 1365} 1366 1367def AsmDialectInterfaceOp : TEST_Op<"asm_dialect_interface_op"> { 1368 let results = (outs AnyType); 1369} 1370 1371//===----------------------------------------------------------------------===// 1372// Test Op Asm Format 1373//===----------------------------------------------------------------------===// 1374 1375def FormatLiteralOp : TEST_Op<"format_literal_op"> { 1376 let assemblyFormat = [{ 1377 `keyword_$.` `->` `:` `,` `=` `<` `>` `(` `)` `[` `]` ` ` `(` ` ` `)` ` ` attr-dict 1378 }]; 1379} 1380 1381// Test that we elide attributes that are within the syntax. 1382def FormatAttrOp : TEST_Op<"format_attr_op"> { 1383 let arguments = (ins I64Attr:$attr); 1384 let assemblyFormat = "$attr attr-dict"; 1385} 1386 1387// Test that we elide optional attributes that are within the syntax. 1388def FormatOptAttrAOp : TEST_Op<"format_opt_attr_op_a"> { 1389 let arguments = (ins OptionalAttr<I64Attr>:$opt_attr); 1390 let assemblyFormat = "(`(` $opt_attr^ `)` )? attr-dict"; 1391} 1392def FormatOptAttrBOp : TEST_Op<"format_opt_attr_op_b"> { 1393 let arguments = (ins OptionalAttr<I64Attr>:$opt_attr); 1394 let assemblyFormat = "($opt_attr^)? attr-dict"; 1395} 1396 1397// Test that we format symbol name attributes properly. 1398def FormatSymbolNameAttrOp : TEST_Op<"format_symbol_name_attr_op"> { 1399 let arguments = (ins SymbolNameAttr:$attr); 1400 let assemblyFormat = "$attr attr-dict"; 1401} 1402 1403// Test that we format optional symbol name attributes properly. 1404def FormatOptSymbolNameAttrOp : TEST_Op<"format_opt_symbol_name_attr_op"> { 1405 let arguments = (ins OptionalAttr<SymbolNameAttr>:$opt_attr); 1406 let assemblyFormat = "($opt_attr^)? attr-dict"; 1407} 1408 1409// Test that we elide attributes that are within the syntax. 1410def FormatAttrDictWithKeywordOp : TEST_Op<"format_attr_dict_w_keyword"> { 1411 let arguments = (ins I64Attr:$attr, OptionalAttr<I64Attr>:$opt_attr); 1412 let assemblyFormat = "attr-dict-with-keyword"; 1413} 1414 1415// Test that we don't need to provide types in the format if they are buildable. 1416def FormatBuildableTypeOp : TEST_Op<"format_buildable_type_op"> { 1417 let arguments = (ins I64:$buildable); 1418 let results = (outs I64:$buildable_res); 1419 let assemblyFormat = "$buildable attr-dict"; 1420} 1421 1422// Test various mixings of region formatting. 1423class FormatRegionBase<string suffix, string fmt> 1424 : TEST_Op<"format_region_" # suffix # "_op"> { 1425 let regions = (region AnyRegion:$region); 1426 let assemblyFormat = fmt; 1427} 1428def FormatRegionAOp : FormatRegionBase<"a", [{ 1429 regions attr-dict 1430}]>; 1431def FormatRegionBOp : FormatRegionBase<"b", [{ 1432 $region attr-dict 1433}]>; 1434def FormatRegionCOp : FormatRegionBase<"c", [{ 1435 (`region` $region^)? attr-dict 1436}]>; 1437class FormatVariadicRegionBase<string suffix, string fmt> 1438 : TEST_Op<"format_variadic_region_" # suffix # "_op"> { 1439 let regions = (region VariadicRegion<AnyRegion>:$regions); 1440 let assemblyFormat = fmt; 1441} 1442def FormatVariadicRegionAOp : FormatVariadicRegionBase<"a", [{ 1443 $regions attr-dict 1444}]>; 1445def FormatVariadicRegionBOp : FormatVariadicRegionBase<"b", [{ 1446 ($regions^ `found_regions`)? attr-dict 1447}]>; 1448class FormatRegionImplicitTerminatorBase<string suffix, string fmt> 1449 : TEST_Op<"format_implicit_terminator_region_" # suffix # "_op", 1450 [SingleBlockImplicitTerminator<"TestReturnOp">]> { 1451 let regions = (region AnyRegion:$region); 1452 let assemblyFormat = fmt; 1453} 1454def FormatFormatRegionImplicitTerminatorAOp 1455 : FormatRegionImplicitTerminatorBase<"a", [{ 1456 $region attr-dict 1457}]>; 1458 1459// Test various mixings of result type formatting. 1460class FormatResultBase<string suffix, string fmt> 1461 : TEST_Op<"format_result_" # suffix # "_op"> { 1462 let results = (outs I64:$buildable_res, AnyMemRef:$result); 1463 let assemblyFormat = fmt; 1464} 1465def FormatResultAOp : FormatResultBase<"a", [{ 1466 type($result) attr-dict 1467}]>; 1468def FormatResultBOp : FormatResultBase<"b", [{ 1469 type(results) attr-dict 1470}]>; 1471def FormatResultCOp : FormatResultBase<"c", [{ 1472 functional-type($buildable_res, $result) attr-dict 1473}]>; 1474 1475// Test various mixings of operand type formatting. 1476class FormatOperandBase<string suffix, string fmt> 1477 : TEST_Op<"format_operand_" # suffix # "_op"> { 1478 let arguments = (ins I64:$buildable, AnyMemRef:$operand); 1479 let assemblyFormat = fmt; 1480} 1481 1482def FormatOperandAOp : FormatOperandBase<"a", [{ 1483 operands `:` type(operands) attr-dict 1484}]>; 1485def FormatOperandBOp : FormatOperandBase<"b", [{ 1486 operands `:` type($operand) attr-dict 1487}]>; 1488def FormatOperandCOp : FormatOperandBase<"c", [{ 1489 $buildable `,` $operand `:` type(operands) attr-dict 1490}]>; 1491def FormatOperandDOp : FormatOperandBase<"d", [{ 1492 $buildable `,` $operand `:` type($operand) attr-dict 1493}]>; 1494def FormatOperandEOp : FormatOperandBase<"e", [{ 1495 $buildable `,` $operand `:` type($buildable) `,` type($operand) attr-dict 1496}]>; 1497 1498def FormatSuccessorAOp : TEST_Op<"format_successor_a_op", [Terminator]> { 1499 let successors = (successor VariadicSuccessor<AnySuccessor>:$targets); 1500 let assemblyFormat = "$targets attr-dict"; 1501} 1502 1503// Test various mixings of optional operand and result type formatting. 1504class FormatOptionalOperandResultOpBase<string suffix, string fmt> 1505 : TEST_Op<"format_optional_operand_result_" # suffix # "_op", 1506 [AttrSizedOperandSegments]> { 1507 let arguments = (ins Optional<I64>:$optional, Variadic<I64>:$variadic); 1508 let results = (outs Optional<I64>:$optional_res); 1509 let assemblyFormat = fmt; 1510} 1511 1512def FormatOptionalOperandResultAOp : FormatOptionalOperandResultOpBase<"a", [{ 1513 `(` $optional `:` type($optional) `)` `:` type($optional_res) 1514 (`[` $variadic^ `]`)? attr-dict 1515}]>; 1516 1517def FormatOptionalOperandResultBOp : FormatOptionalOperandResultOpBase<"b", [{ 1518 (`(` $optional^ `:` type($optional) `)`)? `:` type($optional_res) 1519 (`[` $variadic^ `]`)? attr-dict 1520}]>; 1521 1522def FormatTwoVariadicOperandsNoBuildableTypeOp 1523 : TEST_Op<"format_two_variadic_operands_no_buildable_type_op", 1524 [AttrSizedOperandSegments]> { 1525 let arguments = (ins Variadic<AnyType>:$a, 1526 Variadic<AnyType>:$b); 1527 let assemblyFormat = [{ 1528 `(` $a `:` type($a) `)` `->` `(` $b `:` type($b) `)` attr-dict 1529 }]; 1530} 1531 1532def FormatInferVariadicTypeFromNonVariadic 1533 : TEST_Op<"format_infer_variadic_type_from_non_variadic", 1534 [SameOperandsAndResultType]> { 1535 let arguments = (ins Variadic<AnyType>:$operands); 1536 let results = (outs AnyType:$result); 1537 let assemblyFormat = "$operands attr-dict `:` type($result)"; 1538} 1539 1540def FormatOptionalUnitAttr : TEST_Op<"format_optional_unit_attribute"> { 1541 let arguments = (ins UnitAttr:$is_optional); 1542 let assemblyFormat = "(`is_optional` $is_optional^)? attr-dict"; 1543} 1544 1545def FormatOptionalUnitAttrNoElide 1546 : TEST_Op<"format_optional_unit_attribute_no_elide"> { 1547 let arguments = (ins UnitAttr:$is_optional); 1548 let assemblyFormat = "($is_optional^)? attr-dict"; 1549} 1550 1551//===----------------------------------------------------------------------===// 1552// Custom Directives 1553 1554def FormatCustomDirectiveOperands 1555 : TEST_Op<"format_custom_directive_operands", [AttrSizedOperandSegments]> { 1556 let arguments = (ins I64:$operand, Optional<I64>:$optOperand, 1557 Variadic<I64>:$varOperands); 1558 let assemblyFormat = [{ 1559 custom<CustomDirectiveOperands>( 1560 $operand, $optOperand, $varOperands 1561 ) 1562 attr-dict 1563 }]; 1564} 1565 1566def FormatCustomDirectiveOperandsAndTypes 1567 : TEST_Op<"format_custom_directive_operands_and_types", 1568 [AttrSizedOperandSegments]> { 1569 let arguments = (ins AnyType:$operand, Optional<AnyType>:$optOperand, 1570 Variadic<AnyType>:$varOperands); 1571 let assemblyFormat = [{ 1572 custom<CustomDirectiveOperandsAndTypes>( 1573 $operand, $optOperand, $varOperands, 1574 type($operand), type($optOperand), type($varOperands) 1575 ) 1576 attr-dict 1577 }]; 1578} 1579 1580def FormatCustomDirectiveRegions : TEST_Op<"format_custom_directive_regions"> { 1581 let regions = (region AnyRegion:$region, VariadicRegion<AnyRegion>:$regions); 1582 let assemblyFormat = [{ 1583 custom<CustomDirectiveRegions>( 1584 $region, $regions 1585 ) 1586 attr-dict 1587 }]; 1588} 1589 1590def FormatCustomDirectiveResults 1591 : TEST_Op<"format_custom_directive_results", [AttrSizedResultSegments]> { 1592 let results = (outs AnyType:$result, Optional<AnyType>:$optResult, 1593 Variadic<AnyType>:$varResults); 1594 let assemblyFormat = [{ 1595 custom<CustomDirectiveResults>( 1596 type($result), type($optResult), type($varResults) 1597 ) 1598 attr-dict 1599 }]; 1600} 1601 1602def FormatCustomDirectiveResultsWithTypeRefs 1603 : TEST_Op<"format_custom_directive_results_with_type_refs", 1604 [AttrSizedResultSegments]> { 1605 let results = (outs AnyType:$result, Optional<AnyType>:$optResult, 1606 Variadic<AnyType>:$varResults); 1607 let assemblyFormat = [{ 1608 custom<CustomDirectiveResults>( 1609 type($result), type($optResult), type($varResults) 1610 ) 1611 custom<CustomDirectiveWithTypeRefs>( 1612 type_ref($result), type_ref($optResult), type_ref($varResults) 1613 ) 1614 attr-dict 1615 }]; 1616} 1617 1618def FormatCustomDirectiveSuccessors 1619 : TEST_Op<"format_custom_directive_successors", [Terminator]> { 1620 let successors = (successor AnySuccessor:$successor, 1621 VariadicSuccessor<AnySuccessor>:$successors); 1622 let assemblyFormat = [{ 1623 custom<CustomDirectiveSuccessors>( 1624 $successor, $successors 1625 ) 1626 attr-dict 1627 }]; 1628} 1629 1630def FormatCustomDirectiveAttributes 1631 : TEST_Op<"format_custom_directive_attributes"> { 1632 let arguments = (ins I64Attr:$attr, OptionalAttr<I64Attr>:$optAttr); 1633 let assemblyFormat = [{ 1634 custom<CustomDirectiveAttributes>( 1635 $attr, $optAttr 1636 ) 1637 attr-dict 1638 }]; 1639} 1640 1641//===----------------------------------------------------------------------===// 1642// AllTypesMatch type inference 1643 1644def FormatAllTypesMatchVarOp : TEST_Op<"format_all_types_match_var", [ 1645 AllTypesMatch<["value1", "value2", "result"]> 1646 ]> { 1647 let arguments = (ins AnyType:$value1, AnyType:$value2); 1648 let results = (outs AnyType:$result); 1649 let assemblyFormat = "attr-dict $value1 `,` $value2 `:` type($value1)"; 1650} 1651 1652def FormatAllTypesMatchAttrOp : TEST_Op<"format_all_types_match_attr", [ 1653 AllTypesMatch<["value1", "value2", "result"]> 1654 ]> { 1655 let arguments = (ins AnyAttr:$value1, AnyType:$value2); 1656 let results = (outs AnyType:$result); 1657 let assemblyFormat = "attr-dict $value1 `,` $value2"; 1658} 1659 1660//===----------------------------------------------------------------------===// 1661// TypesMatchWith type inference 1662 1663def FormatTypesMatchVarOp : TEST_Op<"format_types_match_var", [ 1664 TypesMatchWith<"result type matches operand", "value", "result", "$_self"> 1665 ]> { 1666 let arguments = (ins AnyType:$value); 1667 let results = (outs AnyType:$result); 1668 let assemblyFormat = "attr-dict $value `:` type($value)"; 1669} 1670 1671def FormatTypesMatchAttrOp : TEST_Op<"format_types_match_attr", [ 1672 TypesMatchWith<"result type matches constant", "value", "result", "$_self"> 1673 ]> { 1674 let arguments = (ins AnyAttr:$value); 1675 let results = (outs AnyType:$result); 1676 let assemblyFormat = "attr-dict $value"; 1677} 1678 1679//===----------------------------------------------------------------------===// 1680// Test SideEffects 1681//===----------------------------------------------------------------------===// 1682 1683def SideEffectOp : TEST_Op<"side_effect_op", 1684 [DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> { 1685 let results = (outs AnyType:$result); 1686} 1687 1688//===----------------------------------------------------------------------===// 1689// Test RegionBranchOpInterface 1690//===----------------------------------------------------------------------===// 1691 1692def RegionIfYieldOp : TEST_Op<"region_if_yield", 1693 [NoSideEffect, ReturnLike, Terminator]> { 1694 let arguments = (ins Variadic<AnyType>:$results); 1695 let assemblyFormat = [{ 1696 $results `:` type($results) attr-dict 1697 }]; 1698} 1699 1700def RegionIfOp : TEST_Op<"region_if", 1701 [DeclareOpInterfaceMethods<RegionBranchOpInterface>, 1702 SingleBlockImplicitTerminator<"RegionIfYieldOp">, 1703 RecursiveSideEffects]> { 1704 let description =[{ 1705 Represents an abstract if-then-else-join pattern. In this context, the then 1706 and else regions jump to the join region, which finally returns to its 1707 parent op. 1708 }]; 1709 1710 let printer = [{ return ::print(p, *this); }]; 1711 let parser = [{ return ::parseRegionIfOp(parser, result); }]; 1712 let arguments = (ins Variadic<AnyType>); 1713 let results = (outs Variadic<AnyType>:$results); 1714 let regions = (region SizedRegion<1>:$thenRegion, 1715 AnyRegion:$elseRegion, 1716 AnyRegion:$joinRegion); 1717 let extraClassDeclaration = [{ 1718 Block::BlockArgListType getThenArgs() { 1719 return getBody(0)->getArguments(); 1720 } 1721 Block::BlockArgListType getElseArgs() { 1722 return getBody(1)->getArguments(); 1723 } 1724 Block::BlockArgListType getJoinArgs() { 1725 return getBody(2)->getArguments(); 1726 } 1727 OperandRange getSuccessorEntryOperands(unsigned index); 1728 }]; 1729} 1730 1731//===----------------------------------------------------------------------===// 1732// Test TableGen generated build() methods 1733//===----------------------------------------------------------------------===// 1734 1735def TableGenConstant : TEST_Op<"tblgen_constant"> { 1736 let results = (outs AnyType); 1737} 1738 1739// No variadic args or results. 1740def TableGenBuildOp0 : TEST_Op<"tblgen_build_0"> { 1741 let arguments = (ins AnyType:$value); 1742 let results = (outs AnyType:$result); 1743} 1744 1745// Sigle variadic arg and single variadic results. 1746def TableGenBuildOp1 : TEST_Op<"tblgen_build_1"> { 1747 let arguments = (ins Variadic<AnyType>:$inputs); 1748 let results = (outs Variadic<AnyType>:$results); 1749} 1750 1751// Single variadic arg and non-variadic results. 1752def TableGenBuildOp2 : TEST_Op<"tblgen_build_2"> { 1753 let arguments = (ins Variadic<AnyType>:$inputs); 1754 let results = (outs AnyType:$result); 1755} 1756 1757// Single variadic arg and multiple variadic results. 1758def TableGenBuildOp3 : TEST_Op<"tblgen_build_3", [SameVariadicResultSize]> { 1759 let arguments = (ins Variadic<AnyType>:$inputs); 1760 let results = (outs Variadic<AnyType>:$resultA, Variadic<AnyType>:$resultB); 1761} 1762 1763// Single variadic arg, non variadic results, with SameOperandsAndResultType. 1764// Tests suppression of ambiguous build methods for operations with 1765// SameOperandsAndResultType trait. 1766def TableGenBuildOp4 : TEST_Op<"tblgen_build_4", [SameOperandsAndResultType]> { 1767 let arguments = (ins Variadic<AnyType>:$inputs); 1768 let results = (outs AnyType:$result); 1769} 1770 1771// Single variadic arg with SameOperandsAndResultType and InferTypeOpInterface. 1772// Tests suppression of ambiguous build methods for operations with 1773// SameOperandsAndResultType and InferTypeOpInterface. 1774def TableGenBuildOp5 : TEST_Op<"tblgen_build_5", 1775 [SameOperandsAndResultType, InferTypeOpInterface]> { 1776 let arguments = (ins Variadic<AnyType>:$inputs); 1777 let results = (outs AnyType:$result); 1778 1779 let extraClassDeclaration = [{ 1780 static LogicalResult inferReturnTypes(MLIRContext *, 1781 Optional<Location> location, ValueRange operands, 1782 DictionaryAttr attributes, RegionRange regions, 1783 SmallVectorImpl<Type> &inferredReturnTypes) { 1784 inferredReturnTypes.assign({operands[0].getType()}); 1785 return success(); 1786 } 1787 }]; 1788} 1789 1790//===----------------------------------------------------------------------===// 1791// Test BufferPlacement 1792//===----------------------------------------------------------------------===// 1793 1794def GetTupleElementOp: TEST_Op<"get_tuple_element"> { 1795 let description = [{ 1796 Test op that returns a specified element of the tuple. 1797 }]; 1798 1799 let arguments = (ins 1800 TupleOf<[AnyType]>, 1801 I32Attr:$index 1802 ); 1803 let results = (outs AnyType); 1804} 1805 1806def MakeTupleOp: TEST_Op<"make_tuple"> { 1807 let description = [{ 1808 Test op that creates a tuple value from a list of values. 1809 }]; 1810 1811 let arguments = (ins 1812 Variadic<AnyType>:$inputs 1813 ); 1814 let results = (outs TupleOf<[AnyType]>); 1815} 1816 1817#endif // TEST_OPS 1818