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