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