1// RUN: mlir-opt %s -test-pdl-bytecode-pass -split-input-file | FileCheck %s
2
3// Note: Tests here are written using the PDL Interpreter dialect to avoid
4// unnecessarily testing unnecessary aspects of the pattern compilation
5// pipeline. These tests are written such that we can focus solely on the
6// lowering/execution of the bytecode itself.
7
8//===----------------------------------------------------------------------===//
9// pdl_interp::ApplyConstraintOp
10//===----------------------------------------------------------------------===//
11
12module @patterns {
13  pdl_interp.func @matcher(%root : !pdl.operation) {
14    pdl_interp.apply_constraint "multi_entity_constraint"(%root, %root : !pdl.operation, !pdl.operation) -> ^pat, ^end
15
16  ^pat:
17    pdl_interp.apply_constraint "single_entity_constraint"(%root : !pdl.operation) -> ^pat2, ^end
18
19  ^pat2:
20    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
21
22  ^end:
23    pdl_interp.finalize
24  }
25
26  module @rewriters {
27    pdl_interp.func @success(%root : !pdl.operation) {
28      %op = pdl_interp.create_operation "test.replaced_by_pattern"
29      pdl_interp.erase %root
30      pdl_interp.finalize
31    }
32  }
33}
34
35// CHECK-LABEL: test.apply_constraint_1
36// CHECK: "test.replaced_by_pattern"
37module @ir attributes { test.apply_constraint_1 } {
38  "test.op"() { test_attr } : () -> ()
39}
40
41// -----
42
43module @patterns {
44  pdl_interp.func @matcher(%root : !pdl.operation) {
45    %results = pdl_interp.get_results of %root : !pdl.range<value>
46    %types = pdl_interp.get_value_type of %results : !pdl.range<type>
47    pdl_interp.apply_constraint "multi_entity_var_constraint"(%results, %types : !pdl.range<value>, !pdl.range<type>) -> ^pat, ^end
48
49  ^pat:
50    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
51
52  ^end:
53    pdl_interp.finalize
54  }
55
56  module @rewriters {
57    pdl_interp.func @success(%root : !pdl.operation) {
58      %op = pdl_interp.create_operation "test.replaced_by_pattern"
59      pdl_interp.erase %root
60      pdl_interp.finalize
61    }
62  }
63}
64
65// CHECK-LABEL: test.apply_constraint_2
66// CHECK-NOT: "test.replaced_by_pattern"
67// CHECK: "test.replaced_by_pattern"
68module @ir attributes { test.apply_constraint_2 } {
69  "test.failure_op"() { test_attr } : () -> ()
70  "test.success_op"() : () -> (i32, i64)
71}
72
73// -----
74
75//===----------------------------------------------------------------------===//
76// pdl_interp::ApplyRewriteOp
77//===----------------------------------------------------------------------===//
78
79module @patterns {
80  pdl_interp.func @matcher(%root : !pdl.operation) {
81    pdl_interp.check_operation_name of %root is "test.op" -> ^pat, ^end
82
83  ^pat:
84    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
85
86  ^end:
87    pdl_interp.finalize
88  }
89
90  module @rewriters {
91    pdl_interp.func @success(%root : !pdl.operation) {
92      %operand = pdl_interp.get_operand 0 of %root
93      pdl_interp.apply_rewrite "rewriter"(%root, %operand : !pdl.operation, !pdl.value)
94      pdl_interp.finalize
95    }
96  }
97}
98
99// CHECK-LABEL: test.apply_rewrite_1
100// CHECK: %[[INPUT:.*]] = "test.op_input"
101// CHECK-NOT: "test.op"
102// CHECK: "test.success"(%[[INPUT]])
103module @ir attributes { test.apply_rewrite_1 } {
104  %input = "test.op_input"() : () -> i32
105  "test.op"(%input) : (i32) -> ()
106}
107
108// -----
109
110module @patterns {
111  pdl_interp.func @matcher(%root : !pdl.operation) {
112    pdl_interp.check_operation_name of %root is "test.op" -> ^pat, ^end
113
114  ^pat:
115    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
116
117  ^end:
118    pdl_interp.finalize
119  }
120
121  module @rewriters {
122    pdl_interp.func @success(%root : !pdl.operation) {
123      %op = pdl_interp.apply_rewrite "creator"(%root : !pdl.operation) : !pdl.operation
124      pdl_interp.erase %root
125      pdl_interp.finalize
126    }
127  }
128}
129
130// CHECK-LABEL: test.apply_rewrite_2
131// CHECK: "test.success"
132module @ir attributes { test.apply_rewrite_2 } {
133  "test.op"() : () -> ()
134}
135
136// -----
137
138module @patterns {
139  pdl_interp.func @matcher(%root : !pdl.operation) {
140    pdl_interp.check_operation_name of %root is "test.op" -> ^pat, ^end
141
142  ^pat:
143    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
144
145  ^end:
146    pdl_interp.finalize
147  }
148
149  module @rewriters {
150    pdl_interp.func @success(%root : !pdl.operation) {
151      %operands, %types = pdl_interp.apply_rewrite "var_creator"(%root : !pdl.operation) : !pdl.range<value>, !pdl.range<type>
152      %op = pdl_interp.create_operation "test.success"(%operands : !pdl.range<value>) -> (%types : !pdl.range<type>)
153      pdl_interp.replace %root with (%operands : !pdl.range<value>)
154      pdl_interp.finalize
155    }
156  }
157}
158
159// CHECK-LABEL: test.apply_rewrite_3
160// CHECK: %[[OPERAND:.*]] = "test.producer"
161// CHECK: "test.success"(%[[OPERAND]]) : (i32) -> i32
162// CHECK: "test.consumer"(%[[OPERAND]])
163module @ir attributes { test.apply_rewrite_3 } {
164  %first_operand = "test.producer"() : () -> (i32)
165  %operand = "test.op"(%first_operand) : (i32) -> (i32)
166  "test.consumer"(%operand) : (i32) -> ()
167}
168
169// -----
170
171module @patterns {
172  pdl_interp.func @matcher(%root : !pdl.operation) {
173    pdl_interp.check_operation_name of %root is "test.op" -> ^pat, ^end
174
175  ^pat:
176    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
177
178  ^end:
179    pdl_interp.finalize
180  }
181
182  module @rewriters {
183    pdl_interp.func @success(%root : !pdl.operation) {
184      %attr = pdl_interp.apply_rewrite "str_creator" : !pdl.attribute
185      %type = pdl_interp.apply_rewrite "type_creator" : !pdl.type
186      %newOp = pdl_interp.create_operation "test.success" {"attr" = %attr} -> (%type : !pdl.type)
187      pdl_interp.erase %root
188      pdl_interp.finalize
189    }
190  }
191}
192
193// CHECK-LABEL: test.apply_rewrite_4
194// CHECK: "test.success"() {attr = "test.str"} : () -> f32
195module @ir attributes { test.apply_rewrite_4 } {
196  "test.op"() : () -> ()
197}
198
199// -----
200
201//===----------------------------------------------------------------------===//
202// pdl_interp::AreEqualOp
203//===----------------------------------------------------------------------===//
204
205module @patterns {
206  pdl_interp.func @matcher(%root : !pdl.operation) {
207    %test_attr = pdl_interp.create_attribute unit
208    %attr = pdl_interp.get_attribute "test_attr" of %root
209    pdl_interp.are_equal %test_attr, %attr : !pdl.attribute -> ^pat, ^end
210
211  ^pat:
212    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
213
214  ^end:
215    pdl_interp.finalize
216  }
217
218  module @rewriters {
219    pdl_interp.func @success(%root : !pdl.operation) {
220      %op = pdl_interp.create_operation "test.success"
221      pdl_interp.erase %root
222      pdl_interp.finalize
223    }
224  }
225}
226
227// CHECK-LABEL: test.are_equal_1
228// CHECK: "test.success"
229module @ir attributes { test.are_equal_1 } {
230  "test.op"() { test_attr } : () -> ()
231}
232
233// -----
234
235module @patterns {
236  pdl_interp.func @matcher(%root : !pdl.operation) {
237    %const_types = pdl_interp.create_types [i32, i64]
238    %results = pdl_interp.get_results of %root : !pdl.range<value>
239    %result_types = pdl_interp.get_value_type of %results : !pdl.range<type>
240    pdl_interp.are_equal %result_types, %const_types : !pdl.range<type> -> ^pat, ^end
241
242  ^pat:
243    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
244
245  ^end:
246    pdl_interp.finalize
247  }
248
249  module @rewriters {
250    pdl_interp.func @success(%root : !pdl.operation) {
251      %op = pdl_interp.create_operation "test.success"
252      pdl_interp.erase %root
253      pdl_interp.finalize
254    }
255  }
256}
257
258// CHECK-LABEL: test.are_equal_2
259// CHECK: "test.not_equal"
260// CHECK: "test.success"
261// CHECK-NOT: "test.op"
262module @ir attributes { test.are_equal_2 } {
263  "test.not_equal"() : () -> (i32)
264  "test.op"() : () -> (i32, i64)
265}
266
267// -----
268
269//===----------------------------------------------------------------------===//
270// pdl_interp::BranchOp
271//===----------------------------------------------------------------------===//
272
273module @patterns {
274  pdl_interp.func @matcher(%root : !pdl.operation) {
275    pdl_interp.check_operation_name of %root is "test.op" -> ^pat1, ^end
276
277  ^pat1:
278    pdl_interp.branch ^pat2
279
280  ^pat2:
281    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(2), loc([%root]) -> ^end
282
283  ^end:
284    pdl_interp.finalize
285  }
286
287  module @rewriters {
288    pdl_interp.func @success(%root : !pdl.operation) {
289      %op = pdl_interp.create_operation "test.success"
290      pdl_interp.erase %root
291      pdl_interp.finalize
292    }
293  }
294}
295
296// CHECK-LABEL: test.branch_1
297// CHECK: "test.success"
298module @ir attributes { test.branch_1 } {
299  "test.op"() : () -> ()
300}
301
302// -----
303
304//===----------------------------------------------------------------------===//
305// pdl_interp::CheckAttributeOp
306//===----------------------------------------------------------------------===//
307
308module @patterns {
309  pdl_interp.func @matcher(%root : !pdl.operation) {
310    %attr = pdl_interp.get_attribute "test_attr" of %root
311    pdl_interp.check_attribute %attr is unit -> ^pat, ^end
312
313  ^pat:
314    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
315
316  ^end:
317    pdl_interp.finalize
318  }
319
320  module @rewriters {
321    pdl_interp.func @success(%root : !pdl.operation) {
322      %op = pdl_interp.create_operation "test.success"
323      pdl_interp.erase %root
324      pdl_interp.finalize
325    }
326  }
327}
328
329// CHECK-LABEL: test.check_attribute_1
330// CHECK: "test.success"
331module @ir attributes { test.check_attribute_1 } {
332  "test.op"() { test_attr } : () -> ()
333}
334
335// -----
336
337//===----------------------------------------------------------------------===//
338// pdl_interp::CheckOperandCountOp
339//===----------------------------------------------------------------------===//
340
341module @patterns {
342  pdl_interp.func @matcher(%root : !pdl.operation) {
343    pdl_interp.check_operand_count of %root is at_least 1 -> ^exact_check, ^end
344
345  ^exact_check:
346    pdl_interp.check_operand_count of %root is 2 -> ^pat, ^end
347
348  ^pat:
349    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
350
351  ^end:
352    pdl_interp.finalize
353  }
354
355  module @rewriters {
356    pdl_interp.func @success(%root : !pdl.operation) {
357      %op = pdl_interp.create_operation "test.success"
358      pdl_interp.erase %root
359      pdl_interp.finalize
360    }
361  }
362}
363
364// CHECK-LABEL: test.check_operand_count_1
365// CHECK: "test.op"() : () -> i32
366// CHECK: "test.success"
367module @ir attributes { test.check_operand_count_1 } {
368  %operand = "test.op"() : () -> i32
369  "test.op"(%operand, %operand) : (i32, i32) -> ()
370}
371
372// -----
373
374//===----------------------------------------------------------------------===//
375// pdl_interp::CheckOperationNameOp
376//===----------------------------------------------------------------------===//
377
378module @patterns {
379  pdl_interp.func @matcher(%root : !pdl.operation) {
380    pdl_interp.check_operation_name of %root is "test.op" -> ^pat, ^end
381
382  ^pat:
383    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
384
385  ^end:
386    pdl_interp.finalize
387  }
388
389  module @rewriters {
390    pdl_interp.func @success(%root : !pdl.operation) {
391      %op = pdl_interp.create_operation "test.success"
392      pdl_interp.erase %root
393      pdl_interp.finalize
394    }
395  }
396}
397
398// CHECK-LABEL: test.check_operation_name_1
399// CHECK: "test.success"
400module @ir attributes { test.check_operation_name_1 } {
401  "test.op"() : () -> ()
402}
403
404// -----
405
406//===----------------------------------------------------------------------===//
407// pdl_interp::CheckResultCountOp
408//===----------------------------------------------------------------------===//
409
410module @patterns {
411  pdl_interp.func @matcher(%root : !pdl.operation) {
412    pdl_interp.check_result_count of %root is at_least 1 -> ^exact_check, ^end
413
414  ^exact_check:
415    pdl_interp.check_result_count of %root is 2 -> ^pat, ^end
416
417  ^pat:
418    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
419
420  ^end:
421    pdl_interp.finalize
422  }
423
424  module @rewriters {
425    pdl_interp.func @success(%root : !pdl.operation) {
426      %op = pdl_interp.create_operation "test.success"
427      pdl_interp.erase %root
428      pdl_interp.finalize
429    }
430  }
431}
432
433// CHECK-LABEL: test.check_result_count_1
434// CHECK: "test.op"() : () -> i32
435// CHECK: "test.success"() : () -> ()
436// CHECK-NOT: "test.op"() : () -> (i32, i32)
437module @ir attributes { test.check_result_count_1 } {
438  "test.op"() : () -> i32
439  "test.op"() : () -> (i32, i32)
440}
441
442// -----
443
444//===----------------------------------------------------------------------===//
445// pdl_interp::CheckTypeOp
446//===----------------------------------------------------------------------===//
447
448module @patterns {
449  pdl_interp.func @matcher(%root : !pdl.operation) {
450    %attr = pdl_interp.get_attribute "test_attr" of %root
451    pdl_interp.is_not_null %attr : !pdl.attribute -> ^pat1, ^end
452
453  ^pat1:
454    %type = pdl_interp.get_attribute_type of %attr
455    pdl_interp.check_type %type is i32 -> ^pat2, ^end
456
457  ^pat2:
458    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
459
460  ^end:
461    pdl_interp.finalize
462  }
463
464  module @rewriters {
465    pdl_interp.func @success(%root : !pdl.operation) {
466      %op = pdl_interp.create_operation "test.success"
467      pdl_interp.erase %root
468      pdl_interp.finalize
469    }
470  }
471}
472
473// CHECK-LABEL: test.check_type_1
474// CHECK: "test.success"
475module @ir attributes { test.check_type_1 } {
476  "test.op"() { test_attr = 10 : i32 } : () -> ()
477}
478
479// -----
480
481//===----------------------------------------------------------------------===//
482// pdl_interp::CheckTypesOp
483//===----------------------------------------------------------------------===//
484
485module @patterns {
486  pdl_interp.func @matcher(%root : !pdl.operation) {
487    %results = pdl_interp.get_results of %root : !pdl.range<value>
488    %result_types = pdl_interp.get_value_type of %results : !pdl.range<type>
489    pdl_interp.check_types %result_types are [i32] -> ^pat2, ^end
490
491  ^pat2:
492    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
493
494  ^end:
495    pdl_interp.finalize
496  }
497
498  module @rewriters {
499    pdl_interp.func @success(%root : !pdl.operation) {
500      %op = pdl_interp.create_operation "test.success"
501      pdl_interp.erase %root
502      pdl_interp.finalize
503    }
504  }
505}
506
507// CHECK-LABEL: test.check_types_1
508// CHECK: "test.op"() : () -> (i32, i64)
509// CHECK: "test.success"
510// CHECK-NOT: "test.op"() : () -> i32
511module @ir attributes { test.check_types_1 } {
512  "test.op"() : () -> (i32, i64)
513  "test.op"() : () -> i32
514}
515
516// -----
517
518//===----------------------------------------------------------------------===//
519// pdl_interp::ContinueOp
520//===----------------------------------------------------------------------===//
521
522// Fully tested within the tests for other operations.
523
524//===----------------------------------------------------------------------===//
525// pdl_interp::CreateAttributeOp
526//===----------------------------------------------------------------------===//
527
528// Fully tested within the tests for other operations.
529
530//===----------------------------------------------------------------------===//
531// pdl_interp::CreateOperationOp
532//===----------------------------------------------------------------------===//
533
534// Unused operation to force loading the `arithmetic` dialect for the
535// test of type inferrence.
536arith.constant 10
537
538// Test support for inferring the types of an operation.
539module @patterns {
540  pdl_interp.func @matcher(%root : !pdl.operation) {
541    pdl_interp.check_operation_name of %root is "test.op" -> ^pat, ^end
542
543  ^pat:
544    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
545
546  ^end:
547    pdl_interp.finalize
548  }
549
550  module @rewriters {
551    pdl_interp.func @success(%root : !pdl.operation) {
552      %attr = pdl_interp.create_attribute true
553      %cst = pdl_interp.create_operation "arith.constant" {"value" = %attr} -> <inferred>
554      %cstResults = pdl_interp.get_results of %cst : !pdl.range<value>
555      %op = pdl_interp.create_operation "test.success"(%cstResults : !pdl.range<value>)
556      pdl_interp.erase %root
557      pdl_interp.finalize
558    }
559  }
560}
561
562// CHECK-LABEL: test.create_op_infer_results
563// CHECK: %[[CST:.*]] = arith.constant true
564// CHECK: "test.success"(%[[CST]])
565module @ir attributes { test.create_op_infer_results } {
566  %results:2 = "test.op"() : () -> (i64, i64)
567}
568
569// -----
570
571//===----------------------------------------------------------------------===//
572// pdl_interp::CreateTypeOp
573//===----------------------------------------------------------------------===//
574
575module @patterns {
576  pdl_interp.func @matcher(%root : !pdl.operation) {
577    %attr = pdl_interp.get_attribute "test_attr" of %root
578    pdl_interp.is_not_null %attr : !pdl.attribute -> ^pat1, ^end
579
580  ^pat1:
581    %test_type = pdl_interp.create_type i32
582    %type = pdl_interp.get_attribute_type of %attr
583    pdl_interp.are_equal %type, %test_type : !pdl.type -> ^pat2, ^end
584
585  ^pat2:
586    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
587
588  ^end:
589    pdl_interp.finalize
590  }
591
592  module @rewriters {
593    pdl_interp.func @success(%root : !pdl.operation) {
594      %op = pdl_interp.create_operation "test.success"
595      pdl_interp.erase %root
596      pdl_interp.finalize
597    }
598  }
599}
600
601// CHECK-LABEL: test.create_type_1
602// CHECK: "test.success"
603module @ir attributes { test.create_type_1 } {
604  "test.op"() { test_attr = 0 : i32 } : () -> ()
605}
606
607// -----
608
609//===----------------------------------------------------------------------===//
610// pdl_interp::CreateTypesOp
611//===----------------------------------------------------------------------===//
612
613// Fully tested within the tests for other operations.
614
615//===----------------------------------------------------------------------===//
616// pdl_interp::EraseOp
617//===----------------------------------------------------------------------===//
618
619// Fully tested within the tests for other operations.
620
621//===----------------------------------------------------------------------===//
622// pdl_interp::ExtractOp
623//===----------------------------------------------------------------------===//
624
625module @patterns {
626  pdl_interp.func @matcher(%root : !pdl.operation) {
627    %val = pdl_interp.get_result 0 of %root
628    %ops = pdl_interp.get_users of %val : !pdl.value
629    %op1 = pdl_interp.extract 1 of %ops : !pdl.operation
630    pdl_interp.is_not_null %op1 : !pdl.operation -> ^success, ^end
631  ^success:
632    pdl_interp.record_match @rewriters::@success(%op1 : !pdl.operation) : benefit(1), loc([%root]) -> ^end
633  ^end:
634    pdl_interp.finalize
635  }
636
637  module @rewriters {
638    pdl_interp.func @success(%matched : !pdl.operation) {
639      %op = pdl_interp.create_operation "test.success"
640      pdl_interp.erase %matched
641      pdl_interp.finalize
642    }
643  }
644}
645
646// CHECK-LABEL: test.extract_op
647// CHECK: "test.success"
648// CHECK: %[[OPERAND:.*]] = "test.op"
649// CHECK: "test.op"(%[[OPERAND]])
650module @ir attributes { test.extract_op } {
651  %operand = "test.op"() : () -> i32
652  "test.op"(%operand) : (i32) -> (i32)
653  "test.op"(%operand, %operand) : (i32, i32) -> (i32)
654}
655
656// -----
657
658module @patterns {
659  pdl_interp.func @matcher(%root : !pdl.operation) {
660    %vals = pdl_interp.get_results of %root : !pdl.range<value>
661    %types = pdl_interp.get_value_type of %vals : !pdl.range<type>
662    %type1 = pdl_interp.extract 1 of %types : !pdl.type
663    pdl_interp.is_not_null %type1 : !pdl.type -> ^success, ^end
664  ^success:
665    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
666  ^end:
667    pdl_interp.finalize
668  }
669
670  module @rewriters {
671    pdl_interp.func @success(%matched : !pdl.operation) {
672      %op = pdl_interp.create_operation "test.success"
673      pdl_interp.erase %matched
674      pdl_interp.finalize
675    }
676  }
677}
678
679// CHECK-LABEL: test.extract_type
680// CHECK: %[[OPERAND:.*]] = "test.op"
681// CHECK: "test.success"
682// CHECK: "test.op"(%[[OPERAND]])
683module @ir attributes { test.extract_type } {
684  %operand = "test.op"() : () -> i32
685  "test.op"(%operand) : (i32) -> (i32, i32)
686  "test.op"(%operand) : (i32) -> (i32)
687}
688
689// -----
690
691module @patterns {
692  pdl_interp.func @matcher(%root : !pdl.operation) {
693    %vals = pdl_interp.get_results of %root : !pdl.range<value>
694    %val1 = pdl_interp.extract 1 of %vals : !pdl.value
695    pdl_interp.is_not_null %val1 : !pdl.value -> ^success, ^end
696  ^success:
697    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
698  ^end:
699    pdl_interp.finalize
700  }
701
702  module @rewriters {
703    pdl_interp.func @success(%matched : !pdl.operation) {
704      %op = pdl_interp.create_operation "test.success"
705      pdl_interp.erase %matched
706      pdl_interp.finalize
707    }
708  }
709}
710
711// CHECK-LABEL: test.extract_value
712// CHECK: %[[OPERAND:.*]] = "test.op"
713// CHECK: "test.success"
714// CHECK: "test.op"(%[[OPERAND]])
715module @ir attributes { test.extract_value } {
716  %operand = "test.op"() : () -> i32
717  "test.op"(%operand) : (i32) -> (i32, i32)
718  "test.op"(%operand) : (i32) -> (i32)
719}
720
721// -----
722
723//===----------------------------------------------------------------------===//
724// pdl_interp::FinalizeOp
725//===----------------------------------------------------------------------===//
726
727// Fully tested within the tests for other operations.
728
729//===----------------------------------------------------------------------===//
730// pdl_interp::ForEachOp
731//===----------------------------------------------------------------------===//
732
733module @patterns {
734  pdl_interp.func @matcher(%root : !pdl.operation) {
735    %val1 = pdl_interp.get_result 0 of %root
736    %ops1 = pdl_interp.get_users of %val1 : !pdl.value
737    pdl_interp.foreach %op1 : !pdl.operation in %ops1 {
738      %val2 = pdl_interp.get_result 0 of %op1
739      %ops2 = pdl_interp.get_users of %val2 : !pdl.value
740      pdl_interp.foreach %op2 : !pdl.operation in %ops2 {
741        pdl_interp.record_match @rewriters::@success(%op2 : !pdl.operation) : benefit(1), loc([%root]) -> ^cont
742      ^cont:
743        pdl_interp.continue
744      } -> ^cont
745    ^cont:
746      pdl_interp.continue
747    } -> ^end
748  ^end:
749    pdl_interp.finalize
750  }
751
752  module @rewriters {
753    pdl_interp.func @success(%matched : !pdl.operation) {
754      %op = pdl_interp.create_operation "test.success"
755      pdl_interp.erase %matched
756      pdl_interp.finalize
757    }
758  }
759}
760
761// CHECK-LABEL: test.foreach
762// CHECK: "test.success"
763// CHECK: "test.success"
764// CHECK: "test.success"
765// CHECK: "test.success"
766// CHECK: %[[ROOT:.*]] = "test.op"
767// CHECK: %[[VALA:.*]] = "test.op"(%[[ROOT]])
768// CHECK: %[[VALB:.*]] = "test.op"(%[[ROOT]])
769module @ir attributes { test.foreach } {
770  %root = "test.op"() : () -> i32
771  %valA = "test.op"(%root) : (i32) -> (i32)
772  "test.op"(%valA) : (i32) -> (i32)
773  "test.op"(%valA) : (i32) -> (i32)
774  %valB = "test.op"(%root) : (i32) -> (i32)
775  "test.op"(%valB) : (i32) -> (i32)
776  "test.op"(%valB) : (i32) -> (i32)
777}
778
779// -----
780
781//===----------------------------------------------------------------------===//
782// pdl_interp::GetUsersOp
783//===----------------------------------------------------------------------===//
784
785module @patterns {
786  pdl_interp.func @matcher(%root : !pdl.operation) {
787    %val = pdl_interp.get_result 0 of %root
788    %ops = pdl_interp.get_users of %val : !pdl.value
789    pdl_interp.foreach %op : !pdl.operation in %ops {
790      pdl_interp.record_match @rewriters::@success(%op : !pdl.operation) : benefit(1), loc([%root]) -> ^cont
791    ^cont:
792      pdl_interp.continue
793    } -> ^end
794  ^end:
795    pdl_interp.finalize
796  }
797
798  module @rewriters {
799    pdl_interp.func @success(%matched : !pdl.operation) {
800      %op = pdl_interp.create_operation "test.success"
801      pdl_interp.erase %matched
802      pdl_interp.finalize
803    }
804  }
805}
806
807// CHECK-LABEL: test.get_users_of_value
808// CHECK: "test.success"
809// CHECK: "test.success"
810// CHECK: %[[OPERAND:.*]] = "test.op"
811module @ir attributes { test.get_users_of_value } {
812  %operand = "test.op"() : () -> i32
813  "test.op"(%operand) : (i32) -> (i32)
814  "test.op"(%operand, %operand) : (i32, i32) -> (i32)
815}
816
817// -----
818
819module @patterns {
820  pdl_interp.func @matcher(%root : !pdl.operation) {
821    pdl_interp.check_result_count of %root is at_least 2 -> ^next, ^end
822  ^next:
823    %vals = pdl_interp.get_results of %root : !pdl.range<value>
824    %ops = pdl_interp.get_users of %vals : !pdl.range<value>
825    pdl_interp.foreach %op : !pdl.operation in %ops {
826      pdl_interp.record_match @rewriters::@success(%op : !pdl.operation) : benefit(1), loc([%root]) -> ^cont
827    ^cont:
828      pdl_interp.continue
829    } -> ^end
830  ^end:
831    pdl_interp.finalize
832  }
833
834  module @rewriters {
835    pdl_interp.func @success(%matched : !pdl.operation) {
836      %op = pdl_interp.create_operation "test.success"
837      pdl_interp.erase %matched
838      pdl_interp.finalize
839    }
840  }
841}
842
843// CHECK-LABEL: test.get_all_users_of_range
844// CHECK: "test.success"
845// CHECK: "test.success"
846// CHECK: %[[OPERANDS:.*]]:2 = "test.op"
847module @ir attributes { test.get_all_users_of_range } {
848  %operands:2 = "test.op"() : () -> (i32, i32)
849  "test.op"(%operands#0) : (i32) -> (i32)
850  "test.op"(%operands#1) : (i32) -> (i32)
851}
852
853// -----
854
855module @patterns {
856  pdl_interp.func @matcher(%root : !pdl.operation) {
857    pdl_interp.check_result_count of %root is at_least 2 -> ^next, ^end
858  ^next:
859    %vals = pdl_interp.get_results of %root : !pdl.range<value>
860    %val = pdl_interp.extract 0 of %vals : !pdl.value
861    %ops = pdl_interp.get_users of %val : !pdl.value
862    pdl_interp.foreach %op : !pdl.operation in %ops {
863      pdl_interp.record_match @rewriters::@success(%op : !pdl.operation) : benefit(1), loc([%root]) -> ^cont
864    ^cont:
865      pdl_interp.continue
866    } -> ^end
867  ^end:
868    pdl_interp.finalize
869  }
870
871  module @rewriters {
872    pdl_interp.func @success(%matched : !pdl.operation) {
873      %op = pdl_interp.create_operation "test.success"
874      pdl_interp.erase %matched
875      pdl_interp.finalize
876    }
877  }
878}
879
880// CHECK-LABEL: test.get_first_users_of_range
881// CHECK: "test.success"
882// CHECK: %[[OPERANDS:.*]]:2 = "test.op"
883// CHECK: "test.op"
884module @ir attributes { test.get_first_users_of_range } {
885  %operands:2 = "test.op"() : () -> (i32, i32)
886  "test.op"(%operands#0) : (i32) -> (i32)
887  "test.op"(%operands#1) : (i32) -> (i32)
888}
889
890// -----
891
892//===----------------------------------------------------------------------===//
893// pdl_interp::GetAttributeOp
894//===----------------------------------------------------------------------===//
895
896// Fully tested within the tests for other operations.
897
898//===----------------------------------------------------------------------===//
899// pdl_interp::GetAttributeTypeOp
900//===----------------------------------------------------------------------===//
901
902// Fully tested within the tests for other operations.
903
904//===----------------------------------------------------------------------===//
905// pdl_interp::GetDefiningOpOp
906//===----------------------------------------------------------------------===//
907
908module @patterns {
909  pdl_interp.func @matcher(%root : !pdl.operation) {
910    pdl_interp.check_operand_count of %root is 5 -> ^pat1, ^end
911
912  ^pat1:
913    %operand0 = pdl_interp.get_operand 0 of %root
914    %operand4 = pdl_interp.get_operand 4 of %root
915    %defOp0 = pdl_interp.get_defining_op of %operand0 : !pdl.value
916    %defOp4 = pdl_interp.get_defining_op of %operand4 : !pdl.value
917    pdl_interp.are_equal %defOp0, %defOp4 : !pdl.operation -> ^pat2, ^end
918
919  ^pat2:
920    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
921
922  ^end:
923    pdl_interp.finalize
924  }
925
926  module @rewriters {
927    pdl_interp.func @success(%root : !pdl.operation) {
928      %op = pdl_interp.create_operation "test.success"
929      pdl_interp.erase %root
930      pdl_interp.finalize
931    }
932  }
933}
934
935// CHECK-LABEL: test.get_defining_op_1
936// CHECK: %[[OPERAND0:.*]] = "test.op"
937// CHECK: %[[OPERAND1:.*]] = "test.op"
938// CHECK: "test.success"
939// CHECK: "test.op"(%[[OPERAND0]], %[[OPERAND0]], %[[OPERAND0]], %[[OPERAND0]], %[[OPERAND1]])
940module @ir attributes { test.get_defining_op_1 } {
941  %operand = "test.op"() : () -> i32
942  %other_operand = "test.op"() : () -> i32
943  "test.op"(%operand, %operand, %operand, %operand, %operand) : (i32, i32, i32, i32, i32) -> ()
944  "test.op"(%operand, %operand, %operand, %operand, %other_operand) : (i32, i32, i32, i32, i32) -> ()
945}
946
947// -----
948
949//===----------------------------------------------------------------------===//
950// pdl_interp::GetOperandOp
951//===----------------------------------------------------------------------===//
952
953// Fully tested within the tests for other operations.
954
955//===----------------------------------------------------------------------===//
956// pdl_interp::GetOperandsOp
957//===----------------------------------------------------------------------===//
958
959module @patterns {
960  pdl_interp.func @matcher(%root : !pdl.operation) {
961    pdl_interp.check_operand_count of %root is 2 -> ^pat1, ^end
962
963  ^pat1:
964    %operands = pdl_interp.get_operands 0 of %root : !pdl.range<value>
965    %full_operands = pdl_interp.get_operands of %root : !pdl.range<value>
966    pdl_interp.are_equal %operands, %full_operands : !pdl.range<value> -> ^pat2, ^end
967
968  ^pat2:
969    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
970
971  ^end:
972    pdl_interp.finalize
973  }
974
975  module @rewriters {
976    pdl_interp.func @success(%root : !pdl.operation) {
977      %op = pdl_interp.create_operation "test.success"
978      pdl_interp.erase %root
979      pdl_interp.finalize
980    }
981  }
982}
983
984// CHECK-LABEL: test.get_operands_1
985// CHECK: "test.success"
986module @ir attributes { test.get_operands_1 } {
987  %inputs:2 = "test.producer"() : () -> (i32, i32)
988  "test.op"(%inputs#0, %inputs#1) : (i32, i32) -> ()
989}
990
991// -----
992
993// Test all of the various combinations related to `AttrSizedOperandSegments`.
994module @patterns {
995  pdl_interp.func @matcher(%root : !pdl.operation) {
996    pdl_interp.check_operation_name of %root is "test.attr_sized_operands" -> ^pat1, ^end
997
998  ^pat1:
999    %operands_0 = pdl_interp.get_operands 0 of %root : !pdl.range<value>
1000    pdl_interp.is_not_null %operands_0 : !pdl.range<value> -> ^pat2, ^end
1001
1002  ^pat2:
1003    %operands_0_single = pdl_interp.get_operands 0 of %root : !pdl.value
1004    pdl_interp.is_not_null %operands_0_single : !pdl.value -> ^end, ^pat3
1005
1006  ^pat3:
1007    %operands_1 = pdl_interp.get_operands 1 of %root : !pdl.range<value>
1008    pdl_interp.is_not_null %operands_1 : !pdl.range<value> -> ^pat4, ^end
1009
1010  ^pat4:
1011    %operands_1_single = pdl_interp.get_operands 1 of %root : !pdl.value
1012    pdl_interp.is_not_null %operands_1_single : !pdl.value -> ^end, ^pat5
1013
1014  ^pat5:
1015    %operands_2 = pdl_interp.get_operands 2 of %root : !pdl.range<value>
1016    pdl_interp.is_not_null %operands_2 : !pdl.range<value> -> ^pat6, ^end
1017
1018  ^pat6:
1019    %operands_2_single = pdl_interp.get_operands 2 of %root : !pdl.value
1020    pdl_interp.is_not_null %operands_2_single : !pdl.value -> ^pat7, ^end
1021
1022  ^pat7:
1023    %invalid_operands = pdl_interp.get_operands 50 of %root : !pdl.value
1024    pdl_interp.is_not_null %invalid_operands : !pdl.value -> ^end, ^pat8
1025
1026  ^pat8:
1027    pdl_interp.record_match @rewriters::@success(%root, %operands_0, %operands_1, %operands_2, %operands_2_single : !pdl.operation, !pdl.range<value>, !pdl.range<value>, !pdl.range<value>, !pdl.value) : benefit(1), loc([%root]) -> ^end
1028
1029
1030  ^end:
1031    pdl_interp.finalize
1032  }
1033
1034  module @rewriters {
1035    pdl_interp.func @success(%root: !pdl.operation, %operands_0: !pdl.range<value>, %operands_1: !pdl.range<value>, %operands_2: !pdl.range<value>, %operands_2_single: !pdl.value) {
1036      %op0 = pdl_interp.create_operation "test.success"(%operands_0 : !pdl.range<value>)
1037      %op1 = pdl_interp.create_operation "test.success"(%operands_1 : !pdl.range<value>)
1038      %op2 = pdl_interp.create_operation "test.success"(%operands_2 : !pdl.range<value>)
1039      %op3 = pdl_interp.create_operation "test.success"(%operands_2_single : !pdl.value)
1040      pdl_interp.erase %root
1041      pdl_interp.finalize
1042    }
1043  }
1044}
1045
1046// CHECK-LABEL: test.get_operands_2
1047// CHECK-NEXT:  %[[INPUTS:.*]]:5 = "test.producer"() : () -> (i32, i32, i32, i32, i32)
1048// CHECK-NEXT:  "test.success"() : () -> ()
1049// CHECK-NEXT:  "test.success"(%[[INPUTS]]#0, %[[INPUTS]]#1, %[[INPUTS]]#2, %[[INPUTS]]#3) : (i32, i32, i32, i32) -> ()
1050// CHECK-NEXT:  "test.success"(%[[INPUTS]]#4) : (i32) -> ()
1051// CHECK-NEXT:  "test.success"(%[[INPUTS]]#4) : (i32) -> ()
1052module @ir attributes { test.get_operands_2 } {
1053  %inputs:5 = "test.producer"() : () -> (i32, i32, i32, i32, i32)
1054  "test.attr_sized_operands"(%inputs#0, %inputs#1, %inputs#2, %inputs#3, %inputs#4) {operand_segment_sizes = dense<[0, 4, 1, 0]> : vector<4xi32>} : (i32, i32, i32, i32, i32) -> ()
1055}
1056
1057// -----
1058
1059//===----------------------------------------------------------------------===//
1060// pdl_interp::GetResultOp
1061//===----------------------------------------------------------------------===//
1062
1063module @patterns {
1064  pdl_interp.func @matcher(%root : !pdl.operation) {
1065    pdl_interp.check_result_count of %root is 5 -> ^pat1, ^end
1066
1067  ^pat1:
1068    %result0 = pdl_interp.get_result 0 of %root
1069    %result4 = pdl_interp.get_result 4 of %root
1070    %result0_type = pdl_interp.get_value_type of %result0 : !pdl.type
1071    %result4_type = pdl_interp.get_value_type of %result4 : !pdl.type
1072    pdl_interp.are_equal %result0_type, %result4_type : !pdl.type -> ^pat2, ^end
1073
1074  ^pat2:
1075    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
1076
1077  ^end:
1078    pdl_interp.finalize
1079  }
1080
1081  module @rewriters {
1082    pdl_interp.func @success(%root : !pdl.operation) {
1083      %op = pdl_interp.create_operation "test.success"
1084      pdl_interp.erase %root
1085      pdl_interp.finalize
1086    }
1087  }
1088}
1089
1090// CHECK-LABEL: test.get_result_1
1091// CHECK: "test.success"
1092// CHECK: "test.op"() : () -> (i32, i32, i32, i32, i64)
1093module @ir attributes { test.get_result_1 } {
1094  %a:5 = "test.op"() : () -> (i32, i32, i32, i32, i32)
1095  %b:5 = "test.op"() : () -> (i32, i32, i32, i32, i64)
1096}
1097
1098// -----
1099
1100//===----------------------------------------------------------------------===//
1101// pdl_interp::GetResultsOp
1102//===----------------------------------------------------------------------===//
1103
1104module @patterns {
1105  pdl_interp.func @matcher(%root : !pdl.operation) {
1106    pdl_interp.check_result_count of %root is 5 -> ^pat1, ^end
1107
1108  ^pat1:
1109    %results = pdl_interp.get_results 0 of %root : !pdl.range<value>
1110    %full_results = pdl_interp.get_results of %root : !pdl.range<value>
1111    pdl_interp.are_equal %results, %full_results : !pdl.range<value> -> ^pat2, ^end
1112
1113  ^pat2:
1114    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
1115
1116  ^end:
1117    pdl_interp.finalize
1118  }
1119
1120  module @rewriters {
1121    pdl_interp.func @success(%root : !pdl.operation) {
1122      %op = pdl_interp.create_operation "test.success"
1123      pdl_interp.erase %root
1124      pdl_interp.finalize
1125    }
1126  }
1127}
1128
1129// CHECK-LABEL: test.get_results_1
1130// CHECK: "test.success"
1131module @ir attributes { test.get_results_1 } {
1132  %a:5 = "test.producer"() : () -> (i32, i32, i32, i32, i32)
1133}
1134
1135// -----
1136
1137// Test all of the various combinations related to `AttrSizedResultSegments`.
1138module @patterns {
1139  pdl_interp.func @matcher(%root : !pdl.operation) {
1140    pdl_interp.check_operation_name of %root is "test.attr_sized_results" -> ^pat1, ^end
1141
1142  ^pat1:
1143    %results_0 = pdl_interp.get_results 0 of %root : !pdl.range<value>
1144    pdl_interp.is_not_null %results_0 : !pdl.range<value> -> ^pat2, ^end
1145
1146  ^pat2:
1147    %results_0_single = pdl_interp.get_results 0 of %root : !pdl.value
1148    pdl_interp.is_not_null %results_0_single : !pdl.value -> ^end, ^pat3
1149
1150  ^pat3:
1151    %results_1 = pdl_interp.get_results 1 of %root : !pdl.range<value>
1152    pdl_interp.is_not_null %results_1 : !pdl.range<value> -> ^pat4, ^end
1153
1154  ^pat4:
1155    %results_1_single = pdl_interp.get_results 1 of %root : !pdl.value
1156    pdl_interp.is_not_null %results_1_single : !pdl.value -> ^end, ^pat5
1157
1158  ^pat5:
1159    %results_2 = pdl_interp.get_results 2 of %root : !pdl.range<value>
1160    pdl_interp.is_not_null %results_2 : !pdl.range<value> -> ^pat6, ^end
1161
1162  ^pat6:
1163    %results_2_single = pdl_interp.get_results 2 of %root : !pdl.value
1164    pdl_interp.is_not_null %results_2_single : !pdl.value -> ^pat7, ^end
1165
1166  ^pat7:
1167    %invalid_results = pdl_interp.get_results 50 of %root : !pdl.value
1168    pdl_interp.is_not_null %invalid_results : !pdl.value -> ^end, ^pat8
1169
1170  ^pat8:
1171    pdl_interp.record_match @rewriters::@success(%root, %results_0, %results_1, %results_2, %results_2_single : !pdl.operation, !pdl.range<value>, !pdl.range<value>, !pdl.range<value>, !pdl.value) : benefit(1), loc([%root]) -> ^end
1172
1173
1174  ^end:
1175    pdl_interp.finalize
1176  }
1177
1178  module @rewriters {
1179    pdl_interp.func @success(%root: !pdl.operation, %results_0: !pdl.range<value>, %results_1: !pdl.range<value>, %results_2: !pdl.range<value>, %results_2_single: !pdl.value) {
1180      %results_0_types = pdl_interp.get_value_type of %results_0 : !pdl.range<type>
1181      %results_1_types = pdl_interp.get_value_type of %results_1 : !pdl.range<type>
1182      %results_2_types = pdl_interp.get_value_type of %results_2 : !pdl.range<type>
1183      %results_2_single_types = pdl_interp.get_value_type of %results_2_single : !pdl.type
1184
1185      %op0 = pdl_interp.create_operation "test.success" -> (%results_0_types : !pdl.range<type>)
1186      %op1 = pdl_interp.create_operation "test.success" -> (%results_1_types : !pdl.range<type>)
1187      %op2 = pdl_interp.create_operation "test.success" -> (%results_2_types : !pdl.range<type>)
1188      %op3 = pdl_interp.create_operation "test.success" -> (%results_2_single_types : !pdl.type)
1189
1190      %new_results_0 = pdl_interp.get_results of %op0 : !pdl.range<value>
1191      %new_results_1 = pdl_interp.get_results of %op1 : !pdl.range<value>
1192      %new_results_2 = pdl_interp.get_results of %op2 : !pdl.range<value>
1193
1194      pdl_interp.replace %root with (%new_results_0, %new_results_1, %new_results_2 : !pdl.range<value>, !pdl.range<value>, !pdl.range<value>)
1195      pdl_interp.finalize
1196    }
1197  }
1198}
1199
1200// CHECK-LABEL: test.get_results_2
1201// CHECK: "test.success"() : () -> ()
1202// CHECK: %[[RESULTS_1:.*]]:4 = "test.success"() : () -> (i32, i32, i32, i32)
1203// CHECK: %[[RESULTS_2:.*]] = "test.success"() : () -> i32
1204// CHECK: %[[RESULTS_2_SINGLE:.*]] = "test.success"() : () -> i32
1205// CHECK: "test.consumer"(%[[RESULTS_1]]#0, %[[RESULTS_1]]#1, %[[RESULTS_1]]#2, %[[RESULTS_1]]#3, %[[RESULTS_2]]) : (i32, i32, i32, i32, i32) -> ()
1206module @ir attributes { test.get_results_2 } {
1207  %results:5 = "test.attr_sized_results"() {result_segment_sizes = dense<[0, 4, 1, 0]> : vector<4xi32>} : () -> (i32, i32, i32, i32, i32)
1208  "test.consumer"(%results#0, %results#1, %results#2, %results#3, %results#4) : (i32, i32, i32, i32, i32) -> ()
1209}
1210
1211// -----
1212
1213//===----------------------------------------------------------------------===//
1214// pdl_interp::GetValueTypeOp
1215//===----------------------------------------------------------------------===//
1216
1217// Fully tested within the tests for other operations.
1218
1219//===----------------------------------------------------------------------===//
1220// pdl_interp::IsNotNullOp
1221//===----------------------------------------------------------------------===//
1222
1223// Fully tested within the tests for other operations.
1224
1225//===----------------------------------------------------------------------===//
1226// pdl_interp::RecordMatchOp
1227//===----------------------------------------------------------------------===//
1228
1229// Check that the highest benefit pattern is selected.
1230module @patterns {
1231  pdl_interp.func @matcher(%root : !pdl.operation) {
1232    pdl_interp.check_operation_name of %root is "test.op" -> ^pat1, ^end
1233
1234  ^pat1:
1235    pdl_interp.record_match @rewriters::@failure(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^pat2
1236
1237  ^pat2:
1238    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(2), loc([%root]) -> ^end
1239
1240  ^end:
1241    pdl_interp.finalize
1242  }
1243
1244  module @rewriters {
1245    pdl_interp.func @failure(%root : !pdl.operation) {
1246      pdl_interp.erase %root
1247      pdl_interp.finalize
1248    }
1249    pdl_interp.func @success(%root : !pdl.operation) {
1250      %op = pdl_interp.create_operation "test.success"
1251      pdl_interp.erase %root
1252      pdl_interp.finalize
1253    }
1254  }
1255}
1256
1257// CHECK-LABEL: test.record_match_1
1258// CHECK: "test.success"
1259module @ir attributes { test.record_match_1 } {
1260  "test.op"() : () -> ()
1261}
1262
1263// -----
1264
1265// Check that ranges are properly forwarded to the result.
1266module @patterns {
1267  pdl_interp.func @matcher(%root : !pdl.operation) {
1268    pdl_interp.check_operation_name of %root is "test.op" -> ^pat1, ^end
1269
1270  ^pat1:
1271    %operands = pdl_interp.get_operands of %root : !pdl.range<value>
1272    %results = pdl_interp.get_results of %root : !pdl.range<value>
1273    %types = pdl_interp.get_value_type of %results : !pdl.range<type>
1274    pdl_interp.record_match @rewriters::@success(%operands, %types, %root : !pdl.range<value>, !pdl.range<type>, !pdl.operation) : benefit(1), loc([%root]) -> ^end
1275
1276  ^end:
1277    pdl_interp.finalize
1278  }
1279
1280  module @rewriters {
1281    pdl_interp.func @success(%operands: !pdl.range<value>, %types: !pdl.range<type>, %root: !pdl.operation) {
1282      %op = pdl_interp.create_operation "test.success"(%operands : !pdl.range<value>) -> (%types : !pdl.range<type>)
1283      %results = pdl_interp.get_results of %op : !pdl.range<value>
1284      pdl_interp.replace %root with (%results : !pdl.range<value>)
1285      pdl_interp.finalize
1286    }
1287  }
1288}
1289
1290// CHECK-LABEL: test.record_match_2
1291// CHECK: %[[OPERAND:.*]] = "test.producer"() : () -> i32
1292// CHECK: %[[RESULTS:.*]]:2 = "test.success"(%[[OPERAND]]) : (i32) -> (i64, i32)
1293// CHECK: "test.consumer"(%[[RESULTS]]#0, %[[RESULTS]]#1) : (i64, i32) -> ()
1294module @ir attributes { test.record_match_2 } {
1295  %input = "test.producer"() : () -> i32
1296  %results:2 = "test.op"(%input) : (i32) -> (i64, i32)
1297  "test.consumer"(%results#0, %results#1) : (i64, i32) -> ()
1298}
1299
1300// -----
1301
1302//===----------------------------------------------------------------------===//
1303// pdl_interp::ReplaceOp
1304//===----------------------------------------------------------------------===//
1305
1306module @patterns {
1307  pdl_interp.func @matcher(%root : !pdl.operation) {
1308    pdl_interp.check_operation_name of %root is "test.op" -> ^pat, ^end
1309
1310  ^pat:
1311    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
1312
1313  ^end:
1314    pdl_interp.finalize
1315  }
1316
1317  module @rewriters {
1318    pdl_interp.func @success(%root : !pdl.operation) {
1319      %operand = pdl_interp.get_operand 0 of %root
1320      pdl_interp.replace %root with (%operand : !pdl.value)
1321      pdl_interp.finalize
1322    }
1323  }
1324}
1325
1326// CHECK-LABEL: test.replace_op_1
1327// CHECK: %[[INPUT:.*]] = "test.op_input"
1328// CHECK-NOT: "test.op"
1329// CHECK: "test.op_consumer"(%[[INPUT]])
1330module @ir attributes { test.replace_op_1 } {
1331  %input = "test.op_input"() : () -> i32
1332  %result = "test.op"(%input) : (i32) -> i32
1333  "test.op_consumer"(%result) : (i32) -> ()
1334}
1335
1336// -----
1337
1338//===----------------------------------------------------------------------===//
1339// pdl_interp::SwitchAttributeOp
1340//===----------------------------------------------------------------------===//
1341
1342module @patterns {
1343  pdl_interp.func @matcher(%root : !pdl.operation) {
1344    %attr = pdl_interp.get_attribute "test_attr" of %root
1345    pdl_interp.switch_attribute %attr to [0, unit](^end, ^pat) -> ^end
1346
1347  ^pat:
1348    %attr_2 = pdl_interp.get_attribute "test_attr_2" of %root
1349    pdl_interp.switch_attribute %attr_2 to [0, unit](^end, ^end) -> ^pat2
1350
1351  ^pat2:
1352    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
1353
1354  ^end:
1355    pdl_interp.finalize
1356  }
1357
1358  module @rewriters {
1359    pdl_interp.func @success(%root : !pdl.operation) {
1360      %op = pdl_interp.create_operation "test.success"
1361      pdl_interp.erase %root
1362      pdl_interp.finalize
1363    }
1364  }
1365}
1366
1367// CHECK-LABEL: test.switch_attribute_1
1368// CHECK: "test.success"
1369module @ir attributes { test.switch_attribute_1 } {
1370  "test.op"() { test_attr } : () -> ()
1371}
1372
1373// -----
1374
1375//===----------------------------------------------------------------------===//
1376// pdl_interp::SwitchOperandCountOp
1377//===----------------------------------------------------------------------===//
1378
1379module @patterns {
1380  pdl_interp.func @matcher(%root : !pdl.operation) {
1381    pdl_interp.switch_operand_count of %root to dense<[0, 1]> : vector<2xi32>(^end, ^pat) -> ^end
1382
1383  ^pat:
1384    pdl_interp.switch_operand_count of %root to dense<[0, 2]> : vector<2xi32>(^end, ^end) -> ^pat2
1385
1386  ^pat2:
1387    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
1388
1389  ^end:
1390    pdl_interp.finalize
1391  }
1392
1393  module @rewriters {
1394    pdl_interp.func @success(%root : !pdl.operation) {
1395      %op = pdl_interp.create_operation "test.success"
1396      pdl_interp.erase %root
1397      pdl_interp.finalize
1398    }
1399  }
1400}
1401
1402// CHECK-LABEL: test.switch_operand_1
1403// CHECK: "test.success"
1404module @ir attributes { test.switch_operand_1 } {
1405  %input = "test.op_input"() : () -> i32
1406  "test.op"(%input) : (i32) -> ()
1407}
1408
1409// -----
1410
1411//===----------------------------------------------------------------------===//
1412// pdl_interp::SwitchOperationNameOp
1413//===----------------------------------------------------------------------===//
1414
1415module @patterns {
1416  pdl_interp.func @matcher(%root : !pdl.operation) {
1417    pdl_interp.switch_operation_name of %root to ["foo.op", "test.op"](^end, ^pat1) -> ^end
1418
1419  ^pat1:
1420    pdl_interp.switch_operation_name of %root to ["foo.op", "bar.op"](^end, ^end) -> ^pat2
1421
1422  ^pat2:
1423    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
1424
1425  ^end:
1426    pdl_interp.finalize
1427  }
1428
1429  module @rewriters {
1430    pdl_interp.func @success(%root : !pdl.operation) {
1431      %op = pdl_interp.create_operation "test.success"
1432      pdl_interp.erase %root
1433      pdl_interp.finalize
1434    }
1435  }
1436}
1437
1438// CHECK-LABEL: test.switch_operation_name_1
1439// CHECK: "test.success"
1440module @ir attributes { test.switch_operation_name_1 } {
1441  "test.op"() : () -> ()
1442}
1443
1444// -----
1445
1446//===----------------------------------------------------------------------===//
1447// pdl_interp::SwitchResultCountOp
1448//===----------------------------------------------------------------------===//
1449
1450module @patterns {
1451  pdl_interp.func @matcher(%root : !pdl.operation) {
1452    pdl_interp.switch_result_count of %root to dense<[0, 1]> : vector<2xi32>(^end, ^pat) -> ^end
1453
1454  ^pat:
1455    pdl_interp.switch_result_count of %root to dense<[0, 2]> : vector<2xi32>(^end, ^end) -> ^pat2
1456
1457  ^pat2:
1458    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
1459
1460  ^end:
1461    pdl_interp.finalize
1462  }
1463
1464  module @rewriters {
1465    pdl_interp.func @success(%root : !pdl.operation) {
1466      %op = pdl_interp.create_operation "test.success"
1467      pdl_interp.erase %root
1468      pdl_interp.finalize
1469    }
1470  }
1471}
1472
1473// CHECK-LABEL: test.switch_result_1
1474// CHECK: "test.success"
1475module @ir attributes { test.switch_result_1 } {
1476  "test.op"() : () -> i32
1477}
1478
1479// -----
1480
1481//===----------------------------------------------------------------------===//
1482// pdl_interp::SwitchTypeOp
1483//===----------------------------------------------------------------------===//
1484
1485module @patterns {
1486  pdl_interp.func @matcher(%root : !pdl.operation) {
1487    %attr = pdl_interp.get_attribute "test_attr" of %root
1488    pdl_interp.is_not_null %attr : !pdl.attribute -> ^pat1, ^end
1489
1490  ^pat1:
1491    %type = pdl_interp.get_attribute_type of %attr
1492    pdl_interp.switch_type %type to [i32, i64](^pat2, ^end) -> ^end
1493
1494  ^pat2:
1495    pdl_interp.switch_type %type to [i16, i64](^end, ^end) -> ^pat3
1496
1497  ^pat3:
1498    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
1499
1500  ^end:
1501    pdl_interp.finalize
1502  }
1503
1504  module @rewriters {
1505    pdl_interp.func @success(%root : !pdl.operation) {
1506      %op = pdl_interp.create_operation "test.success"
1507      pdl_interp.erase %root
1508      pdl_interp.finalize
1509    }
1510  }
1511}
1512
1513// CHECK-LABEL: test.switch_type_1
1514// CHECK: "test.success"
1515module @ir attributes { test.switch_type_1 } {
1516  "test.op"() { test_attr = 10 : i32 } : () -> ()
1517}
1518
1519// -----
1520
1521//===----------------------------------------------------------------------===//
1522// pdl_interp::SwitchTypesOp
1523//===----------------------------------------------------------------------===//
1524
1525module @patterns {
1526  pdl_interp.func @matcher(%root : !pdl.operation) {
1527    %results = pdl_interp.get_results of %root : !pdl.range<value>
1528    %types = pdl_interp.get_value_type of %results : !pdl.range<type>
1529    pdl_interp.switch_types %types to [[i64, i64], [i32]](^pat2, ^end) -> ^end
1530
1531  ^pat2:
1532    pdl_interp.switch_types %types to [[i32], [i64, i32]](^end, ^end) -> ^pat3
1533
1534  ^pat3:
1535    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
1536
1537  ^end:
1538    pdl_interp.finalize
1539  }
1540
1541  module @rewriters {
1542    pdl_interp.func @success(%root : !pdl.operation) {
1543      %op = pdl_interp.create_operation "test.success"
1544      pdl_interp.erase %root
1545      pdl_interp.finalize
1546    }
1547  }
1548}
1549
1550// CHECK-LABEL: test.switch_types_1
1551// CHECK: "test.success"
1552module @ir attributes { test.switch_types_1 } {
1553  %results:2 = "test.op"() : () -> (i64, i64)
1554}
1555