1 2//===-- TestOpsSyntax.td - Operations for testing syntax ---*- tablegen -*-===// 3// 4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5// See https://llvm.org/LICENSE.txt for license information. 6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef TEST_OPS_SYNTAX 11#define TEST_OPS_SYNTAX 12 13include "TestAttrDefs.td" 14include "TestDialect.td" 15include "TestTypeDefs.td" 16include "mlir/Interfaces/InferTypeOpInterface.td" 17include "mlir/IR/OpBase.td" 18 19class TEST_Op<string mnemonic, list<Trait> traits = []> : 20 Op<Test_Dialect, mnemonic, traits>; 21 22def WrappingRegionOp : TEST_Op<"wrapping_region", 23 [SingleBlockImplicitTerminator<"TestReturnOp">]> { 24 let summary = "wrapping region operation"; 25 let description = [{ 26 Test op wrapping another op in a region, to test calling 27 parseGenericOperation from the custom parser. 28 }]; 29 30 let results = (outs Variadic<AnyType>); 31 let regions = (region SizedRegion<1>:$region); 32 let hasCustomAssemblyFormat = 1; 33} 34 35def PrettyPrintedRegionOp : TEST_Op<"pretty_printed_region", 36 [SingleBlockImplicitTerminator<"TestReturnOp">]> { 37 let summary = "pretty_printed_region operation"; 38 let description = [{ 39 Test-op can be printed either in a "pretty" or "non-pretty" way based on 40 some criteria. The custom parser parsers both the versions while testing 41 APIs: parseCustomOperationName & parseGenericOperationAfterOpName. 42 }]; 43 let arguments = (ins 44 AnyType:$input1, 45 AnyType:$input2 46 ); 47 48 let results = (outs AnyType); 49 let regions = (region SizedRegion<1>:$region); 50 let hasCustomAssemblyFormat = 1; 51} 52 53def PolyForOp : TEST_Op<"polyfor", [OpAsmOpInterface]> { 54 let summary = "polyfor operation"; 55 let description = [{ 56 Test op with multiple region arguments, each argument of index type. 57 }]; 58 let extraClassDeclaration = [{ 59 void getAsmBlockArgumentNames(mlir::Region ®ion, 60 mlir::OpAsmSetValueNameFn setNameFn); 61 }]; 62 let regions = (region SizedRegion<1>:$region); 63 let hasCustomAssemblyFormat = 1; 64} 65 66def TestAttrWithLoc : TEST_Op<"attr_with_loc"> { 67 let summary = "op's attribute has a location"; 68 let arguments = (ins AnyAttr:$loc, AnyAttr:$value); 69 let assemblyFormat = "`(` $value `` custom<OptionalLoc>($loc) `)` attr-dict"; 70} 71 72// ----- 73 74// This is used to test that the fallback for a custom op's parser and printer 75// is the dialect parser and printer hooks. 76def CustomFormatFallbackOp : TEST_Op<"dialect_custom_format_fallback">; 77 78// Ops related to OIList primitive 79def OIListTrivial : TEST_Op<"oilist_with_keywords_only"> { 80 let arguments = (ins UnitAttr:$keyword, UnitAttr:$otherKeyword, 81 UnitAttr:$diffNameUnitAttrKeyword); 82 let assemblyFormat = [{ 83 oilist( `keyword` $keyword 84 | `otherKeyword` $otherKeyword 85 | `thirdKeyword` $diffNameUnitAttrKeyword) attr-dict 86 }]; 87} 88 89// Ops related to OIList primitive 90def OIListTrivialProperties : TEST_Op<"oilist_with_keywords_only_properties"> { 91 let arguments = (ins UnitProp:$keyword, UnitProp:$otherKeyword, 92 UnitProp:$diffNameUnitPropKeyword); 93 let assemblyFormat = [{ 94 oilist( `keyword` $keyword 95 | `otherKeyword` $otherKeyword 96 | `thirdKeyword` $diffNameUnitPropKeyword) attr-dict 97 }]; 98} 99 100def OIListSimple : TEST_Op<"oilist_with_simple_args", [AttrSizedOperandSegments]> { 101 let arguments = (ins Optional<AnyType>:$arg0, 102 Optional<AnyType>:$arg1, 103 Optional<AnyType>:$arg2); 104 let assemblyFormat = [{ 105 oilist( `keyword` $arg0 `:` type($arg0) 106 | `otherKeyword` $arg1 `:` type($arg1) 107 | `thirdKeyword` $arg2 `:` type($arg2) ) attr-dict 108 }]; 109} 110 111def OIListVariadic : TEST_Op<"oilist_variadic_with_parens", [AttrSizedOperandSegments]> { 112 let arguments = (ins Variadic<AnyType>:$arg0, 113 Variadic<AnyType>:$arg1, 114 Variadic<AnyType>:$arg2); 115 let assemblyFormat = [{ 116 oilist( `keyword` `(` $arg0 `:` type($arg0) `)` 117 | `otherKeyword` `(` $arg1 `:` type($arg1) `)` 118 | `thirdKeyword` `(` $arg2 `:` type($arg2) `)`) attr-dict 119 }]; 120} 121 122def OIListCustom : TEST_Op<"oilist_custom", [AttrSizedOperandSegments]> { 123 let arguments = (ins Variadic<AnyType>:$arg0, 124 Optional<I32>:$optOperand, 125 UnitAttr:$nowait); 126 let assemblyFormat = [{ 127 oilist( `private` `(` $arg0 `:` type($arg0) `)` 128 | `reduction` custom<CustomOptionalOperand>($optOperand) 129 | `nowait` $nowait 130 ) attr-dict 131 }]; 132} 133 134def OIListAllowedLiteral : TEST_Op<"oilist_allowed_literal"> { 135 let assemblyFormat = [{ 136 oilist( `foo` | `bar` ) `buzz` attr-dict 137 }]; 138} 139 140def TestEllipsisOp : TEST_Op<"ellipsis"> { 141 let arguments = (ins Variadic<AnyType>:$operands, UnitAttr:$variadic); 142 let assemblyFormat = [{ 143 `(` $operands (`...` $variadic^)? `)` attr-dict `:` type($operands) `...` 144 }]; 145} 146 147def ElseAnchorOp : TEST_Op<"else_anchor"> { 148 let arguments = (ins Optional<AnyType>:$a); 149 let assemblyFormat = "`(` (`?`) : (`` $a^ `:` type($a))? `)` attr-dict"; 150} 151 152// This is used to test that the default dialect is not elided when printing an 153// op with dots in the name to avoid parsing ambiguity. 154def OpWithDotInNameOp : TEST_Op<"op.with_dot_in_name"> { 155 let assemblyFormat = "attr-dict"; 156} 157 158// -------------- 159 160//===----------------------------------------------------------------------===// 161// Test Op Asm Format 162//===----------------------------------------------------------------------===// 163 164def FormatLiteralOp : TEST_Op<"format_literal_op"> { 165 let assemblyFormat = [{ 166 `keyword_$.` `->` `:` `,` `=` `<` `>` `(` `)` `[` `]` `` `(` ` ` `)` 167 `?` `+` `*` `{` `\n` `}` attr-dict 168 }]; 169} 170 171// Test that we elide attributes that are within the syntax. 172def FormatAttrOp : TEST_Op<"format_attr_op"> { 173 let arguments = (ins I64Attr:$attr); 174 let assemblyFormat = "$attr attr-dict"; 175} 176 177// Test that we elide optional attributes that are within the syntax. 178def FormatOptAttrAOp : TEST_Op<"format_opt_attr_op_a"> { 179 let arguments = (ins OptionalAttr<I64Attr>:$opt_attr); 180 let assemblyFormat = "(`(` $opt_attr^ `)` )? attr-dict"; 181} 182def FormatOptAttrBOp : TEST_Op<"format_opt_attr_op_b"> { 183 let arguments = (ins OptionalAttr<I64Attr>:$opt_attr); 184 let assemblyFormat = "($opt_attr^)? attr-dict"; 185} 186 187// Test that we format symbol name attributes properly. 188def FormatSymbolNameAttrOp : TEST_Op<"format_symbol_name_attr_op"> { 189 let arguments = (ins SymbolNameAttr:$attr); 190 let assemblyFormat = "$attr attr-dict"; 191} 192 193// Test that we format optional symbol name attributes properly. 194def FormatOptSymbolNameAttrOp : TEST_Op<"format_opt_symbol_name_attr_op"> { 195 let arguments = (ins OptionalAttr<SymbolNameAttr>:$opt_attr); 196 let assemblyFormat = "($opt_attr^)? attr-dict"; 197} 198 199// Test that we format optional symbol reference attributes properly. 200def FormatOptSymbolRefAttrOp : TEST_Op<"format_opt_symbol_ref_attr_op"> { 201 let arguments = (ins OptionalAttr<SymbolRefAttr>:$opt_attr); 202 let assemblyFormat = "($opt_attr^)? attr-dict"; 203} 204 205// Test that we elide attributes that are within the syntax. 206def FormatAttrDictWithKeywordOp : TEST_Op<"format_attr_dict_w_keyword"> { 207 let arguments = (ins I64Attr:$attr, OptionalAttr<I64Attr>:$opt_attr); 208 let assemblyFormat = "attr-dict-with-keyword"; 209} 210 211// Test that we don't need to provide types in the format if they are buildable. 212def FormatBuildableTypeOp : TEST_Op<"format_buildable_type_op"> { 213 let arguments = (ins I64:$buildable); 214 let results = (outs I64:$buildable_res); 215 let assemblyFormat = "$buildable attr-dict"; 216} 217 218// Test various mixings of region formatting. 219class FormatRegionBase<string suffix, string fmt> 220 : TEST_Op<"format_region_" # suffix # "_op"> { 221 let regions = (region AnyRegion:$region); 222 let assemblyFormat = fmt; 223} 224def FormatRegionAOp : FormatRegionBase<"a", [{ 225 regions attr-dict 226}]>; 227def FormatRegionBOp : FormatRegionBase<"b", [{ 228 $region attr-dict 229}]>; 230def FormatRegionCOp : FormatRegionBase<"c", [{ 231 (`region` $region^)? attr-dict 232}]>; 233class FormatVariadicRegionBase<string suffix, string fmt> 234 : TEST_Op<"format_variadic_region_" # suffix # "_op"> { 235 let regions = (region VariadicRegion<AnyRegion>:$regions); 236 let assemblyFormat = fmt; 237} 238def FormatVariadicRegionAOp : FormatVariadicRegionBase<"a", [{ 239 $regions attr-dict 240}]>; 241def FormatVariadicRegionBOp : FormatVariadicRegionBase<"b", [{ 242 ($regions^ `found_regions`)? attr-dict 243}]>; 244class FormatRegionImplicitTerminatorBase<string suffix, string fmt> 245 : TEST_Op<"format_implicit_terminator_region_" # suffix # "_op", 246 [SingleBlockImplicitTerminator<"TestReturnOp">]> { 247 let regions = (region AnyRegion:$region); 248 let assemblyFormat = fmt; 249} 250def FormatFormatRegionImplicitTerminatorAOp 251 : FormatRegionImplicitTerminatorBase<"a", [{ 252 $region attr-dict 253}]>; 254 255// Test various mixings of result type formatting. 256class FormatResultBase<string suffix, string fmt> 257 : TEST_Op<"format_result_" # suffix # "_op"> { 258 let results = (outs I64:$buildable_res, AnyMemRef:$result); 259 let assemblyFormat = fmt; 260} 261def FormatResultAOp : FormatResultBase<"a", [{ 262 type($result) attr-dict 263}]>; 264def FormatResultBOp : FormatResultBase<"b", [{ 265 type(results) attr-dict 266}]>; 267def FormatResultCOp : FormatResultBase<"c", [{ 268 functional-type($buildable_res, $result) attr-dict 269}]>; 270 271def FormatVariadicResult : TEST_Op<"format_variadic_result"> { 272 let results = (outs Variadic<I64>:$result); 273 let assemblyFormat = [{ `:` type($result) attr-dict}]; 274} 275 276def FormatMultipleVariadicResults : TEST_Op<"format_multiple_variadic_results", 277 [AttrSizedResultSegments]> { 278 let results = (outs Variadic<I64>:$result0, Variadic<AnyType>:$result1); 279 let assemblyFormat = [{ 280 `:` `(` type($result0) `)` `,` `(` type($result1) `)` attr-dict 281 }]; 282} 283 284// Test various mixings of operand type formatting. 285class FormatOperandBase<string suffix, string fmt> 286 : TEST_Op<"format_operand_" # suffix # "_op"> { 287 let arguments = (ins I64:$buildable, AnyMemRef:$operand); 288 let assemblyFormat = fmt; 289} 290 291def FormatOperandAOp : FormatOperandBase<"a", [{ 292 operands `:` type(operands) attr-dict 293}]>; 294def FormatOperandBOp : FormatOperandBase<"b", [{ 295 operands `:` type($operand) attr-dict 296}]>; 297def FormatOperandCOp : FormatOperandBase<"c", [{ 298 $buildable `,` $operand `:` type(operands) attr-dict 299}]>; 300def FormatOperandDOp : FormatOperandBase<"d", [{ 301 $buildable `,` $operand `:` type($operand) attr-dict 302}]>; 303def FormatOperandEOp : FormatOperandBase<"e", [{ 304 $buildable `,` $operand `:` type($buildable) `,` type($operand) attr-dict 305}]>; 306 307def FormatSuccessorAOp : TEST_Op<"format_successor_a_op", [Terminator]> { 308 let successors = (successor VariadicSuccessor<AnySuccessor>:$targets); 309 let assemblyFormat = "$targets attr-dict"; 310} 311 312def FormatVariadicOperand : TEST_Op<"format_variadic_operand"> { 313 let arguments = (ins Variadic<I64>:$operand); 314 let assemblyFormat = [{ $operand `:` type($operand) attr-dict}]; 315} 316def FormatVariadicOfVariadicOperand 317 : TEST_Op<"format_variadic_of_variadic_operand"> { 318 let arguments = (ins 319 VariadicOfVariadic<I64, "operand_segments">:$operand, 320 DenseI32ArrayAttr:$operand_segments 321 ); 322 let assemblyFormat = [{ $operand `:` type($operand) attr-dict}]; 323} 324 325def FormatMultipleVariadicOperands : 326 TEST_Op<"format_multiple_variadic_operands", [AttrSizedOperandSegments]> { 327 let arguments = (ins Variadic<I64>:$operand0, Variadic<AnyType>:$operand1); 328 let assemblyFormat = [{ 329 ` ` `(` $operand0 `)` `,` `(` $operand1 `:` type($operand1) `)` attr-dict 330 }]; 331} 332 333// Test various mixings of optional operand and result type formatting. 334class FormatOptionalOperandResultOpBase<string suffix, string fmt> 335 : TEST_Op<"format_optional_operand_result_" # suffix # "_op", 336 [AttrSizedOperandSegments]> { 337 let arguments = (ins Optional<I64>:$optional, Variadic<I64>:$variadic); 338 let results = (outs Optional<I64>:$optional_res); 339 let assemblyFormat = fmt; 340} 341 342def FormatOptionalOperandResultAOp : FormatOptionalOperandResultOpBase<"a", [{ 343 `(` $optional `:` type($optional) `)` `:` type($optional_res) 344 (`[` $variadic^ `]`)? attr-dict 345}]>; 346 347def FormatOptionalOperandResultBOp : FormatOptionalOperandResultOpBase<"b", [{ 348 (`(` $optional^ `:` type($optional) `)`)? `:` type($optional_res) 349 (`[` $variadic^ `]`)? attr-dict 350}]>; 351 352// Test optional result type formatting. 353class FormatOptionalResultOpBase<string suffix, string fmt> 354 : TEST_Op<"format_optional_result_" # suffix # "_op", 355 [AttrSizedResultSegments]> { 356 let results = (outs Optional<I64>:$optional, Variadic<I64>:$variadic); 357 let assemblyFormat = fmt; 358} 359def FormatOptionalResultAOp : FormatOptionalResultOpBase<"a", [{ 360 (`:` type($optional)^ `->` type($variadic))? attr-dict 361}]>; 362 363def FormatOptionalResultBOp : FormatOptionalResultOpBase<"b", [{ 364 (`:` type($optional) `->` type($variadic)^)? attr-dict 365}]>; 366 367def FormatOptionalResultCOp : FormatOptionalResultOpBase<"c", [{ 368 (`:` functional-type($optional, $variadic)^)? attr-dict 369}]>; 370 371def FormatOptionalResultDOp 372 : TEST_Op<"format_optional_result_d_op" > { 373 let results = (outs Optional<F80>:$optional); 374 let assemblyFormat = "(`:` type($optional)^)? attr-dict"; 375} 376 377def FormatTwoVariadicOperandsNoBuildableTypeOp 378 : TEST_Op<"format_two_variadic_operands_no_buildable_type_op", 379 [AttrSizedOperandSegments]> { 380 let arguments = (ins Variadic<AnyType>:$a, 381 Variadic<AnyType>:$b); 382 let assemblyFormat = [{ 383 `(` $a `:` type($a) `)` `->` `(` $b `:` type($b) `)` attr-dict 384 }]; 385} 386 387def FormatInferVariadicTypeFromNonVariadic 388 : TEST_Op<"format_infer_variadic_type_from_non_variadic", 389 [SameOperandsAndResultType]> { 390 let arguments = (ins Variadic<AnyType>:$args); 391 let results = (outs AnyType:$result); 392 let assemblyFormat = "operands attr-dict `:` type($result)"; 393} 394 395def FormatOptionalUnitAttr : TEST_Op<"format_optional_unit_attribute"> { 396 let arguments = (ins UnitAttr:$is_optional); 397 let assemblyFormat = "(`is_optional` $is_optional^)? attr-dict"; 398} 399 400def FormatOptionalUnitAttrNoElide 401 : TEST_Op<"format_optional_unit_attribute_no_elide"> { 402 let arguments = (ins UnitAttr:$is_optional); 403 let assemblyFormat = "($is_optional^)? attr-dict"; 404} 405 406def FormatOptionalUnitProperty : TEST_Op<"format_optional_unit_property"> { 407 let arguments = (ins UnitProp:$is_optional); 408 let assemblyFormat = "(`is_optional` $is_optional^)? attr-dict"; 409} 410 411def FormatOptionalUnitPropertyNoElide 412 : TEST_Op<"format_optional_unit_property_no_elide"> { 413 let arguments = (ins UnitProp:$is_optional); 414 let assemblyFormat = "($is_optional^)? attr-dict"; 415} 416 417def FormatOptionalEnumAttr : TEST_Op<"format_optional_enum_attr"> { 418 let arguments = (ins OptionalAttr<SomeI64Enum>:$attr); 419 let assemblyFormat = "($attr^)? attr-dict"; 420} 421 422def FormatOptionalDefaultAttrs : TEST_Op<"format_optional_default_attrs"> { 423 let arguments = (ins DefaultValuedStrAttr<StrAttr, "default">:$str, 424 DefaultValuedStrAttr<SymbolNameAttr, "default">:$sym, 425 DefaultValuedAttr<SomeI64Enum, "SomeI64Enum::case5">:$e); 426 let assemblyFormat = "($str^)? ($sym^)? ($e^)? attr-dict"; 427} 428 429def FormatOptionalWithElse : TEST_Op<"format_optional_else"> { 430 let arguments = (ins UnitAttr:$isFirstBranchPresent); 431 let assemblyFormat = "(`then` $isFirstBranchPresent^):(`else`)? attr-dict"; 432} 433 434def FormatOptionalPropDict : TEST_Op<"format_optional_prop_dict"> { 435 let arguments = (ins 436 OptionalProp<StringProp>:$a, 437 DefaultValuedProp<I32Prop, "1">:$b); 438 let assemblyFormat = "prop-dict attr-dict"; 439} 440 441def FormatCompoundAttr : TEST_Op<"format_compound_attr"> { 442 let arguments = (ins CompoundAttrA:$compound); 443 let assemblyFormat = "$compound attr-dict-with-keyword"; 444} 445 446def FormatNestedAttr : TEST_Op<"format_nested_attr"> { 447 let arguments = (ins CompoundAttrNested:$nested); 448 let assemblyFormat = "$nested attr-dict-with-keyword"; 449} 450 451def FormatNestedCompoundAttr : TEST_Op<"format_cpmd_nested_attr"> { 452 let arguments = (ins CompoundNestedOuter:$nested); 453 let assemblyFormat = "`nested` $nested attr-dict-with-keyword"; 454} 455 456def FormatMaybeEmptyType : TEST_Op<"format_maybe_empty_type"> { 457 let arguments = (ins TestTypeOptionalValueType:$in); 458 let assemblyFormat = "$in `:` type($in) attr-dict"; 459} 460 461def FormatQualifiedCompoundAttr : TEST_Op<"format_qual_cpmd_nested_attr"> { 462 let arguments = (ins CompoundNestedOuter:$nested); 463 let assemblyFormat = "`nested` qualified($nested) attr-dict-with-keyword"; 464} 465 466def FormatNestedType : TEST_Op<"format_cpmd_nested_type"> { 467 let arguments = (ins CompoundNestedOuterType:$nested); 468 let assemblyFormat = "$nested `nested` type($nested) attr-dict-with-keyword"; 469} 470 471def FormatQualifiedNestedType : TEST_Op<"format_qual_cpmd_nested_type"> { 472 let arguments = (ins CompoundNestedOuterType:$nested); 473 let assemblyFormat = "$nested `nested` qualified(type($nested)) attr-dict-with-keyword"; 474} 475 476//===----------------------------------------------------------------------===// 477// Custom Directives 478 479def FormatCustomDirectiveOperands 480 : TEST_Op<"format_custom_directive_operands", [AttrSizedOperandSegments]> { 481 let arguments = (ins I64:$operand, Optional<I64>:$optOperand, 482 Variadic<I64>:$varOperands); 483 let assemblyFormat = [{ 484 custom<CustomDirectiveOperands>( 485 $operand, $optOperand, $varOperands 486 ) 487 attr-dict 488 }]; 489} 490 491def FormatCustomDirectiveOperandsAndTypes 492 : TEST_Op<"format_custom_directive_operands_and_types", 493 [AttrSizedOperandSegments]> { 494 let arguments = (ins AnyType:$operand, Optional<AnyType>:$optOperand, 495 Variadic<AnyType>:$varOperands); 496 let assemblyFormat = [{ 497 custom<CustomDirectiveOperandsAndTypes>( 498 $operand, $optOperand, $varOperands, 499 type($operand), type($optOperand), type($varOperands) 500 ) 501 attr-dict 502 }]; 503} 504 505def FormatCustomDirectiveRegions : TEST_Op<"format_custom_directive_regions"> { 506 let regions = (region AnyRegion:$region, VariadicRegion<AnyRegion>:$other_regions); 507 let assemblyFormat = [{ 508 custom<CustomDirectiveRegions>( 509 $region, $other_regions 510 ) 511 attr-dict 512 }]; 513} 514 515def FormatCustomDirectiveResults 516 : TEST_Op<"format_custom_directive_results", [AttrSizedResultSegments]> { 517 let results = (outs AnyType:$result, Optional<AnyType>:$optResult, 518 Variadic<AnyType>:$varResults); 519 let assemblyFormat = [{ 520 custom<CustomDirectiveResults>( 521 type($result), type($optResult), type($varResults) 522 ) 523 attr-dict 524 }]; 525} 526 527def FormatCustomDirectiveResultsWithTypeRefs 528 : TEST_Op<"format_custom_directive_results_with_type_refs", 529 [AttrSizedResultSegments]> { 530 let results = (outs AnyType:$result, Optional<AnyType>:$optResult, 531 Variadic<AnyType>:$varResults); 532 let assemblyFormat = [{ 533 custom<CustomDirectiveResults>( 534 type($result), type($optResult), type($varResults) 535 ) 536 custom<CustomDirectiveWithTypeRefs>( 537 ref(type($result)), ref(type($optResult)), ref(type($varResults)) 538 ) 539 attr-dict 540 }]; 541} 542 543def FormatCustomDirectiveWithOptionalOperandRef 544 : TEST_Op<"format_custom_directive_with_optional_operand_ref"> { 545 let arguments = (ins Optional<I64>:$optOperand); 546 let assemblyFormat = [{ 547 ($optOperand^)? `:` 548 custom<CustomDirectiveOptionalOperandRef>(ref($optOperand)) 549 attr-dict 550 }]; 551} 552 553def FormatCustomDirectiveSuccessors 554 : TEST_Op<"format_custom_directive_successors", [Terminator]> { 555 let successors = (successor AnySuccessor:$successor, 556 VariadicSuccessor<AnySuccessor>:$successors); 557 let assemblyFormat = [{ 558 custom<CustomDirectiveSuccessors>( 559 $successor, $successors 560 ) 561 attr-dict 562 }]; 563} 564 565def FormatCustomDirectiveAttributes 566 : TEST_Op<"format_custom_directive_attributes"> { 567 let arguments = (ins I64Attr:$attr, OptionalAttr<I64Attr>:$optAttr); 568 let assemblyFormat = [{ 569 custom<CustomDirectiveAttributes>( 570 $attr, $optAttr 571 ) 572 attr-dict 573 }]; 574} 575 576def FormatCustomDirectiveSpacing 577 : TEST_Op<"format_custom_directive_spacing"> { 578 let arguments = (ins StrAttr:$attr1, StrAttr:$attr2); 579 let assemblyFormat = [{ 580 custom<CustomDirectiveSpacing>($attr1) 581 custom<CustomDirectiveSpacing>($attr2) 582 attr-dict 583 }]; 584} 585 586def FormatCustomDirectiveAttrDict 587 : TEST_Op<"format_custom_directive_attrdict"> { 588 let arguments = (ins I64Attr:$attr, OptionalAttr<I64Attr>:$optAttr); 589 let assemblyFormat = [{ 590 custom<CustomDirectiveAttrDict>( attr-dict ) 591 }]; 592} 593 594def FormatLiteralFollowingOptionalGroup 595 : TEST_Op<"format_literal_following_optional_group"> { 596 let arguments = (ins TypeAttr:$type, OptionalAttr<AnyAttr>:$value); 597 let assemblyFormat = "(`(` $value^ `)`)? `:` $type attr-dict"; 598} 599 600//===----------------------------------------------------------------------===// 601// AllTypesMatch type inference 602 603def FormatAllTypesMatchVarOp : TEST_Op<"format_all_types_match_var", [ 604 AllTypesMatch<["value1", "value2", "result"]> 605 ]> { 606 let arguments = (ins AnyType:$value1, AnyType:$value2); 607 let results = (outs AnyType:$result); 608 let assemblyFormat = "attr-dict $value1 `,` $value2 `:` type($value1)"; 609} 610 611def FormatAllTypesMatchAttrOp : TEST_Op<"format_all_types_match_attr", [ 612 AllTypesMatch<["value1", "value2", "result"]> 613 ]> { 614 let arguments = (ins TypedAttrInterface:$value1, AnyType:$value2); 615 let results = (outs AnyType:$result); 616 let assemblyFormat = "attr-dict $value1 `,` $value2"; 617} 618 619//===----------------------------------------------------------------------===// 620// TypesMatchWith type inference 621 622def FormatTypesMatchVarOp : TEST_Op<"format_types_match_var", [ 623 TypesMatchWith<"result type matches operand", "value", "result", "$_self"> 624 ]> { 625 let arguments = (ins AnyType:$value); 626 let results = (outs AnyType:$result); 627 let assemblyFormat = "attr-dict $value `:` type($value)"; 628} 629 630def FormatTypesMatchVariadicOp : TEST_Op<"format_types_match_variadic", [ 631 RangedTypesMatchWith<"result type matches operand", "value", "result", 632 "llvm::make_range($_self.begin(), $_self.end())"> 633 ]> { 634 let arguments = (ins Variadic<AnyType>:$value); 635 let results = (outs Variadic<AnyType>:$result); 636 let assemblyFormat = "attr-dict $value `:` type($value)"; 637} 638 639def FormatTypesMatchAttrOp : TEST_Op<"format_types_match_attr", [ 640 TypesMatchWith<"result type matches constant", "value", "result", "$_self"> 641 ]> { 642 let arguments = (ins TypedAttrInterface:$value); 643 let results = (outs AnyType:$result); 644 let assemblyFormat = "attr-dict $value"; 645} 646 647def FormatTypesMatchContextOp : TEST_Op<"format_types_match_context", [ 648 TypesMatchWith<"tuple result type matches operand type", "value", "result", 649 "::mlir::TupleType::get($_ctxt, $_self)"> 650 ]> { 651 let arguments = (ins AnyType:$value); 652 let results = (outs AnyType:$result); 653 let assemblyFormat = "attr-dict $value `:` type($value)"; 654} 655 656//===----------------------------------------------------------------------===// 657// InferTypeOpInterface type inference in assembly format 658 659def FormatInferTypeOp : TEST_Op<"format_infer_type", [InferTypeOpInterface]> { 660 let results = (outs AnyType); 661 let assemblyFormat = "attr-dict"; 662 663 let extraClassDeclaration = [{ 664 static ::llvm::LogicalResult inferReturnTypes(::mlir::MLIRContext *context, 665 ::std::optional<::mlir::Location> location, ::mlir::ValueRange operands, 666 ::mlir::DictionaryAttr attributes, mlir::OpaqueProperties properties, ::mlir::RegionRange regions, 667 ::llvm::SmallVectorImpl<::mlir::Type> &inferredReturnTypes) { 668 inferredReturnTypes.assign({::mlir::IntegerType::get(context, 16)}); 669 return ::mlir::success(); 670 } 671 }]; 672} 673 674// Check that formatget supports DeclareOpInterfaceMethods. 675def FormatInferType2Op : TEST_Op<"format_infer_type2", [DeclareOpInterfaceMethods<InferTypeOpInterface>]> { 676 let results = (outs AnyType); 677 let assemblyFormat = "attr-dict"; 678} 679 680// Base class for testing mixing allOperandTypes, allOperands, and 681// inferResultTypes. 682class FormatInferAllTypesBaseOp<string mnemonic, list<Trait> traits = []> 683 : TEST_Op<mnemonic, [InferTypeOpInterface] # traits> { 684 let arguments = (ins Variadic<AnyType>:$args); 685 let results = (outs Variadic<AnyType>:$outs); 686 let extraClassDeclaration = [{ 687 static ::llvm::LogicalResult inferReturnTypes(::mlir::MLIRContext *context, 688 ::std::optional<::mlir::Location> location, ::mlir::ValueRange operands, 689 ::mlir::DictionaryAttr attributes, mlir::OpaqueProperties properties, ::mlir::RegionRange regions, 690 ::llvm::SmallVectorImpl<::mlir::Type> &inferredReturnTypes) { 691 ::mlir::TypeRange operandTypes = operands.getTypes(); 692 inferredReturnTypes.assign(operandTypes.begin(), operandTypes.end()); 693 return ::mlir::success(); 694 } 695 }]; 696} 697 698// Test inferReturnTypes is called when allOperandTypes and allOperands is true. 699def FormatInferTypeAllOperandsAndTypesOp 700 : FormatInferAllTypesBaseOp<"format_infer_type_all_operands_and_types"> { 701 let assemblyFormat = "`(` operands `)` attr-dict `:` type(operands)"; 702} 703 704// Test inferReturnTypes is called when allOperandTypes is true and there is one 705// ODS operand. 706def FormatInferTypeAllOperandsAndTypesOneOperandOp 707 : FormatInferAllTypesBaseOp<"format_infer_type_all_types_one_operand"> { 708 let assemblyFormat = "`(` $args `)` attr-dict `:` type(operands)"; 709} 710 711// Test inferReturnTypes is called when allOperandTypes is true and there are 712// more than one ODS operands. 713def FormatInferTypeAllOperandsAndTypesTwoOperandsOp 714 : FormatInferAllTypesBaseOp<"format_infer_type_all_types_two_operands", 715 [SameVariadicOperandSize]> { 716 let arguments = (ins Variadic<AnyType>:$args0, Variadic<AnyType>:$args1); 717 let assemblyFormat = "`(` $args0 `)` `(` $args1 `)` attr-dict `:` type(operands)"; 718} 719 720// Test inferReturnTypes is called when allOperands is true and operand types 721// are separately specified. 722def FormatInferTypeAllTypesOp 723 : FormatInferAllTypesBaseOp<"format_infer_type_all_types"> { 724 let assemblyFormat = "`(` operands `)` attr-dict `:` type($args)"; 725} 726 727// Test inferReturnTypes coupled with regions. 728def FormatInferTypeRegionsOp 729 : TEST_Op<"format_infer_type_regions", [InferTypeOpInterface]> { 730 let results = (outs Variadic<AnyType>:$outs); 731 let regions = (region AnyRegion:$region); 732 let assemblyFormat = "$region attr-dict"; 733 let extraClassDeclaration = [{ 734 static ::llvm::LogicalResult inferReturnTypes(::mlir::MLIRContext *context, 735 ::std::optional<::mlir::Location> location, ::mlir::ValueRange operands, 736 ::mlir::DictionaryAttr attributes, mlir::OpaqueProperties properties, ::mlir::RegionRange regions, 737 ::llvm::SmallVectorImpl<::mlir::Type> &inferredReturnTypes) { 738 if (regions.empty()) 739 return ::mlir::failure(); 740 auto types = regions.front()->getArgumentTypes(); 741 inferredReturnTypes.assign(types.begin(), types.end()); 742 return ::mlir::success(); 743 } 744 }]; 745} 746 747// Test inferReturnTypes coupled with variadic operands (operandSegmentSizes). 748def FormatInferTypeVariadicOperandsOp 749 : TEST_Op<"format_infer_type_variadic_operands", 750 [InferTypeOpInterface, AttrSizedOperandSegments]> { 751 let arguments = (ins Variadic<I32>:$a, Variadic<I64>:$b); 752 let results = (outs Variadic<AnyType>:$outs); 753 let assemblyFormat = "`(` $a `:` type($a) `)` `(` $b `:` type($b) `)` attr-dict"; 754 let extraClassDeclaration = [{ 755 static ::llvm::LogicalResult inferReturnTypes(::mlir::MLIRContext *context, 756 ::std::optional<::mlir::Location> location, ::mlir::ValueRange operands, 757 ::mlir::DictionaryAttr attributes, mlir::OpaqueProperties properties, ::mlir::RegionRange regions, 758 ::llvm::SmallVectorImpl<::mlir::Type> &inferredReturnTypes) { 759 FormatInferTypeVariadicOperandsOpAdaptor adaptor( 760 operands, attributes, *properties.as<Properties *>(), {}); 761 auto aTypes = adaptor.getA().getTypes(); 762 auto bTypes = adaptor.getB().getTypes(); 763 inferredReturnTypes.append(aTypes.begin(), aTypes.end()); 764 inferredReturnTypes.append(bTypes.begin(), bTypes.end()); 765 return ::mlir::success(); 766 } 767 }]; 768} 769 770#endif // TEST_OPS_SYNTAX 771