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// -----
535
536//===----------------------------------------------------------------------===//
537// pdl_interp::CreateTypeOp
538//===----------------------------------------------------------------------===//
539
540module @patterns {
541  pdl_interp.func @matcher(%root : !pdl.operation) {
542    %attr = pdl_interp.get_attribute "test_attr" of %root
543    pdl_interp.is_not_null %attr : !pdl.attribute -> ^pat1, ^end
544
545  ^pat1:
546    %test_type = pdl_interp.create_type i32
547    %type = pdl_interp.get_attribute_type of %attr
548    pdl_interp.are_equal %type, %test_type : !pdl.type -> ^pat2, ^end
549
550  ^pat2:
551    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
552
553  ^end:
554    pdl_interp.finalize
555  }
556
557  module @rewriters {
558    pdl_interp.func @success(%root : !pdl.operation) {
559      %op = pdl_interp.create_operation "test.success"
560      pdl_interp.erase %root
561      pdl_interp.finalize
562    }
563  }
564}
565
566// CHECK-LABEL: test.create_type_1
567// CHECK: "test.success"
568module @ir attributes { test.create_type_1 } {
569  "test.op"() { test_attr = 0 : i32 } : () -> ()
570}
571
572// -----
573
574//===----------------------------------------------------------------------===//
575// pdl_interp::CreateTypesOp
576//===----------------------------------------------------------------------===//
577
578// Fully tested within the tests for other operations.
579
580//===----------------------------------------------------------------------===//
581// pdl_interp::EraseOp
582//===----------------------------------------------------------------------===//
583
584// Fully tested within the tests for other operations.
585
586//===----------------------------------------------------------------------===//
587// pdl_interp::ExtractOp
588//===----------------------------------------------------------------------===//
589
590module @patterns {
591  pdl_interp.func @matcher(%root : !pdl.operation) {
592    %val = pdl_interp.get_result 0 of %root
593    %ops = pdl_interp.get_users of %val : !pdl.value
594    %op1 = pdl_interp.extract 1 of %ops : !pdl.operation
595    pdl_interp.is_not_null %op1 : !pdl.operation -> ^success, ^end
596  ^success:
597    pdl_interp.record_match @rewriters::@success(%op1 : !pdl.operation) : benefit(1), loc([%root]) -> ^end
598  ^end:
599    pdl_interp.finalize
600  }
601
602  module @rewriters {
603    pdl_interp.func @success(%matched : !pdl.operation) {
604      %op = pdl_interp.create_operation "test.success"
605      pdl_interp.erase %matched
606      pdl_interp.finalize
607    }
608  }
609}
610
611// CHECK-LABEL: test.extract_op
612// CHECK: "test.success"
613// CHECK: %[[OPERAND:.*]] = "test.op"
614// CHECK: "test.op"(%[[OPERAND]])
615module @ir attributes { test.extract_op } {
616  %operand = "test.op"() : () -> i32
617  "test.op"(%operand) : (i32) -> (i32)
618  "test.op"(%operand, %operand) : (i32, i32) -> (i32)
619}
620
621// -----
622
623module @patterns {
624  pdl_interp.func @matcher(%root : !pdl.operation) {
625    %vals = pdl_interp.get_results of %root : !pdl.range<value>
626    %types = pdl_interp.get_value_type of %vals : !pdl.range<type>
627    %type1 = pdl_interp.extract 1 of %types : !pdl.type
628    pdl_interp.is_not_null %type1 : !pdl.type -> ^success, ^end
629  ^success:
630    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
631  ^end:
632    pdl_interp.finalize
633  }
634
635  module @rewriters {
636    pdl_interp.func @success(%matched : !pdl.operation) {
637      %op = pdl_interp.create_operation "test.success"
638      pdl_interp.erase %matched
639      pdl_interp.finalize
640    }
641  }
642}
643
644// CHECK-LABEL: test.extract_type
645// CHECK: %[[OPERAND:.*]] = "test.op"
646// CHECK: "test.success"
647// CHECK: "test.op"(%[[OPERAND]])
648module @ir attributes { test.extract_type } {
649  %operand = "test.op"() : () -> i32
650  "test.op"(%operand) : (i32) -> (i32, i32)
651  "test.op"(%operand) : (i32) -> (i32)
652}
653
654// -----
655
656module @patterns {
657  pdl_interp.func @matcher(%root : !pdl.operation) {
658    %vals = pdl_interp.get_results of %root : !pdl.range<value>
659    %val1 = pdl_interp.extract 1 of %vals : !pdl.value
660    pdl_interp.is_not_null %val1 : !pdl.value -> ^success, ^end
661  ^success:
662    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
663  ^end:
664    pdl_interp.finalize
665  }
666
667  module @rewriters {
668    pdl_interp.func @success(%matched : !pdl.operation) {
669      %op = pdl_interp.create_operation "test.success"
670      pdl_interp.erase %matched
671      pdl_interp.finalize
672    }
673  }
674}
675
676// CHECK-LABEL: test.extract_value
677// CHECK: %[[OPERAND:.*]] = "test.op"
678// CHECK: "test.success"
679// CHECK: "test.op"(%[[OPERAND]])
680module @ir attributes { test.extract_value } {
681  %operand = "test.op"() : () -> i32
682  "test.op"(%operand) : (i32) -> (i32, i32)
683  "test.op"(%operand) : (i32) -> (i32)
684}
685
686// -----
687
688//===----------------------------------------------------------------------===//
689// pdl_interp::FinalizeOp
690//===----------------------------------------------------------------------===//
691
692// Fully tested within the tests for other operations.
693
694//===----------------------------------------------------------------------===//
695// pdl_interp::ForEachOp
696//===----------------------------------------------------------------------===//
697
698module @patterns {
699  pdl_interp.func @matcher(%root : !pdl.operation) {
700    %val1 = pdl_interp.get_result 0 of %root
701    %ops1 = pdl_interp.get_users of %val1 : !pdl.value
702    pdl_interp.foreach %op1 : !pdl.operation in %ops1 {
703      %val2 = pdl_interp.get_result 0 of %op1
704      %ops2 = pdl_interp.get_users of %val2 : !pdl.value
705      pdl_interp.foreach %op2 : !pdl.operation in %ops2 {
706        pdl_interp.record_match @rewriters::@success(%op2 : !pdl.operation) : benefit(1), loc([%root]) -> ^cont
707      ^cont:
708        pdl_interp.continue
709      } -> ^cont
710    ^cont:
711      pdl_interp.continue
712    } -> ^end
713  ^end:
714    pdl_interp.finalize
715  }
716
717  module @rewriters {
718    pdl_interp.func @success(%matched : !pdl.operation) {
719      %op = pdl_interp.create_operation "test.success"
720      pdl_interp.erase %matched
721      pdl_interp.finalize
722    }
723  }
724}
725
726// CHECK-LABEL: test.foreach
727// CHECK: "test.success"
728// CHECK: "test.success"
729// CHECK: "test.success"
730// CHECK: "test.success"
731// CHECK: %[[ROOT:.*]] = "test.op"
732// CHECK: %[[VALA:.*]] = "test.op"(%[[ROOT]])
733// CHECK: %[[VALB:.*]] = "test.op"(%[[ROOT]])
734module @ir attributes { test.foreach } {
735  %root = "test.op"() : () -> i32
736  %valA = "test.op"(%root) : (i32) -> (i32)
737  "test.op"(%valA) : (i32) -> (i32)
738  "test.op"(%valA) : (i32) -> (i32)
739  %valB = "test.op"(%root) : (i32) -> (i32)
740  "test.op"(%valB) : (i32) -> (i32)
741  "test.op"(%valB) : (i32) -> (i32)
742}
743
744// -----
745
746//===----------------------------------------------------------------------===//
747// pdl_interp::GetUsersOp
748//===----------------------------------------------------------------------===//
749
750module @patterns {
751  pdl_interp.func @matcher(%root : !pdl.operation) {
752    %val = pdl_interp.get_result 0 of %root
753    %ops = pdl_interp.get_users of %val : !pdl.value
754    pdl_interp.foreach %op : !pdl.operation in %ops {
755      pdl_interp.record_match @rewriters::@success(%op : !pdl.operation) : benefit(1), loc([%root]) -> ^cont
756    ^cont:
757      pdl_interp.continue
758    } -> ^end
759  ^end:
760    pdl_interp.finalize
761  }
762
763  module @rewriters {
764    pdl_interp.func @success(%matched : !pdl.operation) {
765      %op = pdl_interp.create_operation "test.success"
766      pdl_interp.erase %matched
767      pdl_interp.finalize
768    }
769  }
770}
771
772// CHECK-LABEL: test.get_users_of_value
773// CHECK: "test.success"
774// CHECK: "test.success"
775// CHECK: %[[OPERAND:.*]] = "test.op"
776module @ir attributes { test.get_users_of_value } {
777  %operand = "test.op"() : () -> i32
778  "test.op"(%operand) : (i32) -> (i32)
779  "test.op"(%operand, %operand) : (i32, i32) -> (i32)
780}
781
782// -----
783
784module @patterns {
785  pdl_interp.func @matcher(%root : !pdl.operation) {
786    pdl_interp.check_result_count of %root is at_least 2 -> ^next, ^end
787  ^next:
788    %vals = pdl_interp.get_results of %root : !pdl.range<value>
789    %ops = pdl_interp.get_users of %vals : !pdl.range<value>
790    pdl_interp.foreach %op : !pdl.operation in %ops {
791      pdl_interp.record_match @rewriters::@success(%op : !pdl.operation) : benefit(1), loc([%root]) -> ^cont
792    ^cont:
793      pdl_interp.continue
794    } -> ^end
795  ^end:
796    pdl_interp.finalize
797  }
798
799  module @rewriters {
800    pdl_interp.func @success(%matched : !pdl.operation) {
801      %op = pdl_interp.create_operation "test.success"
802      pdl_interp.erase %matched
803      pdl_interp.finalize
804    }
805  }
806}
807
808// CHECK-LABEL: test.get_all_users_of_range
809// CHECK: "test.success"
810// CHECK: "test.success"
811// CHECK: %[[OPERANDS:.*]]:2 = "test.op"
812module @ir attributes { test.get_all_users_of_range } {
813  %operands:2 = "test.op"() : () -> (i32, i32)
814  "test.op"(%operands#0) : (i32) -> (i32)
815  "test.op"(%operands#1) : (i32) -> (i32)
816}
817
818// -----
819
820module @patterns {
821  pdl_interp.func @matcher(%root : !pdl.operation) {
822    pdl_interp.check_result_count of %root is at_least 2 -> ^next, ^end
823  ^next:
824    %vals = pdl_interp.get_results of %root : !pdl.range<value>
825    %val = pdl_interp.extract 0 of %vals : !pdl.value
826    %ops = pdl_interp.get_users of %val : !pdl.value
827    pdl_interp.foreach %op : !pdl.operation in %ops {
828      pdl_interp.record_match @rewriters::@success(%op : !pdl.operation) : benefit(1), loc([%root]) -> ^cont
829    ^cont:
830      pdl_interp.continue
831    } -> ^end
832  ^end:
833    pdl_interp.finalize
834  }
835
836  module @rewriters {
837    pdl_interp.func @success(%matched : !pdl.operation) {
838      %op = pdl_interp.create_operation "test.success"
839      pdl_interp.erase %matched
840      pdl_interp.finalize
841    }
842  }
843}
844
845// CHECK-LABEL: test.get_first_users_of_range
846// CHECK: "test.success"
847// CHECK: %[[OPERANDS:.*]]:2 = "test.op"
848// CHECK: "test.op"
849module @ir attributes { test.get_first_users_of_range } {
850  %operands:2 = "test.op"() : () -> (i32, i32)
851  "test.op"(%operands#0) : (i32) -> (i32)
852  "test.op"(%operands#1) : (i32) -> (i32)
853}
854
855// -----
856
857//===----------------------------------------------------------------------===//
858// pdl_interp::GetAttributeOp
859//===----------------------------------------------------------------------===//
860
861// Fully tested within the tests for other operations.
862
863//===----------------------------------------------------------------------===//
864// pdl_interp::GetAttributeTypeOp
865//===----------------------------------------------------------------------===//
866
867// Fully tested within the tests for other operations.
868
869//===----------------------------------------------------------------------===//
870// pdl_interp::GetDefiningOpOp
871//===----------------------------------------------------------------------===//
872
873module @patterns {
874  pdl_interp.func @matcher(%root : !pdl.operation) {
875    pdl_interp.check_operand_count of %root is 5 -> ^pat1, ^end
876
877  ^pat1:
878    %operand0 = pdl_interp.get_operand 0 of %root
879    %operand4 = pdl_interp.get_operand 4 of %root
880    %defOp0 = pdl_interp.get_defining_op of %operand0 : !pdl.value
881    %defOp4 = pdl_interp.get_defining_op of %operand4 : !pdl.value
882    pdl_interp.are_equal %defOp0, %defOp4 : !pdl.operation -> ^pat2, ^end
883
884  ^pat2:
885    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
886
887  ^end:
888    pdl_interp.finalize
889  }
890
891  module @rewriters {
892    pdl_interp.func @success(%root : !pdl.operation) {
893      %op = pdl_interp.create_operation "test.success"
894      pdl_interp.erase %root
895      pdl_interp.finalize
896    }
897  }
898}
899
900// CHECK-LABEL: test.get_defining_op_1
901// CHECK: %[[OPERAND0:.*]] = "test.op"
902// CHECK: %[[OPERAND1:.*]] = "test.op"
903// CHECK: "test.success"
904// CHECK: "test.op"(%[[OPERAND0]], %[[OPERAND0]], %[[OPERAND0]], %[[OPERAND0]], %[[OPERAND1]])
905module @ir attributes { test.get_defining_op_1 } {
906  %operand = "test.op"() : () -> i32
907  %other_operand = "test.op"() : () -> i32
908  "test.op"(%operand, %operand, %operand, %operand, %operand) : (i32, i32, i32, i32, i32) -> ()
909  "test.op"(%operand, %operand, %operand, %operand, %other_operand) : (i32, i32, i32, i32, i32) -> ()
910}
911
912// -----
913
914//===----------------------------------------------------------------------===//
915// pdl_interp::GetOperandOp
916//===----------------------------------------------------------------------===//
917
918// Fully tested within the tests for other operations.
919
920//===----------------------------------------------------------------------===//
921// pdl_interp::GetOperandsOp
922//===----------------------------------------------------------------------===//
923
924module @patterns {
925  pdl_interp.func @matcher(%root : !pdl.operation) {
926    pdl_interp.check_operand_count of %root is 2 -> ^pat1, ^end
927
928  ^pat1:
929    %operands = pdl_interp.get_operands 0 of %root : !pdl.range<value>
930    %full_operands = pdl_interp.get_operands of %root : !pdl.range<value>
931    pdl_interp.are_equal %operands, %full_operands : !pdl.range<value> -> ^pat2, ^end
932
933  ^pat2:
934    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
935
936  ^end:
937    pdl_interp.finalize
938  }
939
940  module @rewriters {
941    pdl_interp.func @success(%root : !pdl.operation) {
942      %op = pdl_interp.create_operation "test.success"
943      pdl_interp.erase %root
944      pdl_interp.finalize
945    }
946  }
947}
948
949// CHECK-LABEL: test.get_operands_1
950// CHECK: "test.success"
951module @ir attributes { test.get_operands_1 } {
952  %inputs:2 = "test.producer"() : () -> (i32, i32)
953  "test.op"(%inputs#0, %inputs#1) : (i32, i32) -> ()
954}
955
956// -----
957
958// Test all of the various combinations related to `AttrSizedOperandSegments`.
959module @patterns {
960  pdl_interp.func @matcher(%root : !pdl.operation) {
961    pdl_interp.check_operation_name of %root is "test.attr_sized_operands" -> ^pat1, ^end
962
963  ^pat1:
964    %operands_0 = pdl_interp.get_operands 0 of %root : !pdl.range<value>
965    pdl_interp.is_not_null %operands_0 : !pdl.range<value> -> ^pat2, ^end
966
967  ^pat2:
968    %operands_0_single = pdl_interp.get_operands 0 of %root : !pdl.value
969    pdl_interp.is_not_null %operands_0_single : !pdl.value -> ^end, ^pat3
970
971  ^pat3:
972    %operands_1 = pdl_interp.get_operands 1 of %root : !pdl.range<value>
973    pdl_interp.is_not_null %operands_1 : !pdl.range<value> -> ^pat4, ^end
974
975  ^pat4:
976    %operands_1_single = pdl_interp.get_operands 1 of %root : !pdl.value
977    pdl_interp.is_not_null %operands_1_single : !pdl.value -> ^end, ^pat5
978
979  ^pat5:
980    %operands_2 = pdl_interp.get_operands 2 of %root : !pdl.range<value>
981    pdl_interp.is_not_null %operands_2 : !pdl.range<value> -> ^pat6, ^end
982
983  ^pat6:
984    %operands_2_single = pdl_interp.get_operands 2 of %root : !pdl.value
985    pdl_interp.is_not_null %operands_2_single : !pdl.value -> ^pat7, ^end
986
987  ^pat7:
988    %invalid_operands = pdl_interp.get_operands 50 of %root : !pdl.value
989    pdl_interp.is_not_null %invalid_operands : !pdl.value -> ^end, ^pat8
990
991  ^pat8:
992    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
993
994
995  ^end:
996    pdl_interp.finalize
997  }
998
999  module @rewriters {
1000    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) {
1001      %op0 = pdl_interp.create_operation "test.success"(%operands_0 : !pdl.range<value>)
1002      %op1 = pdl_interp.create_operation "test.success"(%operands_1 : !pdl.range<value>)
1003      %op2 = pdl_interp.create_operation "test.success"(%operands_2 : !pdl.range<value>)
1004      %op3 = pdl_interp.create_operation "test.success"(%operands_2_single : !pdl.value)
1005      pdl_interp.erase %root
1006      pdl_interp.finalize
1007    }
1008  }
1009}
1010
1011// CHECK-LABEL: test.get_operands_2
1012// CHECK-NEXT:  %[[INPUTS:.*]]:5 = "test.producer"() : () -> (i32, i32, i32, i32, i32)
1013// CHECK-NEXT:  "test.success"() : () -> ()
1014// CHECK-NEXT:  "test.success"(%[[INPUTS]]#0, %[[INPUTS]]#1, %[[INPUTS]]#2, %[[INPUTS]]#3) : (i32, i32, i32, i32) -> ()
1015// CHECK-NEXT:  "test.success"(%[[INPUTS]]#4) : (i32) -> ()
1016// CHECK-NEXT:  "test.success"(%[[INPUTS]]#4) : (i32) -> ()
1017module @ir attributes { test.get_operands_2 } {
1018  %inputs:5 = "test.producer"() : () -> (i32, i32, i32, i32, i32)
1019  "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) -> ()
1020}
1021
1022// -----
1023
1024//===----------------------------------------------------------------------===//
1025// pdl_interp::GetResultOp
1026//===----------------------------------------------------------------------===//
1027
1028module @patterns {
1029  pdl_interp.func @matcher(%root : !pdl.operation) {
1030    pdl_interp.check_result_count of %root is 5 -> ^pat1, ^end
1031
1032  ^pat1:
1033    %result0 = pdl_interp.get_result 0 of %root
1034    %result4 = pdl_interp.get_result 4 of %root
1035    %result0_type = pdl_interp.get_value_type of %result0 : !pdl.type
1036    %result4_type = pdl_interp.get_value_type of %result4 : !pdl.type
1037    pdl_interp.are_equal %result0_type, %result4_type : !pdl.type -> ^pat2, ^end
1038
1039  ^pat2:
1040    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
1041
1042  ^end:
1043    pdl_interp.finalize
1044  }
1045
1046  module @rewriters {
1047    pdl_interp.func @success(%root : !pdl.operation) {
1048      %op = pdl_interp.create_operation "test.success"
1049      pdl_interp.erase %root
1050      pdl_interp.finalize
1051    }
1052  }
1053}
1054
1055// CHECK-LABEL: test.get_result_1
1056// CHECK: "test.success"
1057// CHECK: "test.op"() : () -> (i32, i32, i32, i32, i64)
1058module @ir attributes { test.get_result_1 } {
1059  %a:5 = "test.op"() : () -> (i32, i32, i32, i32, i32)
1060  %b:5 = "test.op"() : () -> (i32, i32, i32, i32, i64)
1061}
1062
1063// -----
1064
1065//===----------------------------------------------------------------------===//
1066// pdl_interp::GetResultsOp
1067//===----------------------------------------------------------------------===//
1068
1069module @patterns {
1070  pdl_interp.func @matcher(%root : !pdl.operation) {
1071    pdl_interp.check_result_count of %root is 5 -> ^pat1, ^end
1072
1073  ^pat1:
1074    %results = pdl_interp.get_results 0 of %root : !pdl.range<value>
1075    %full_results = pdl_interp.get_results of %root : !pdl.range<value>
1076    pdl_interp.are_equal %results, %full_results : !pdl.range<value> -> ^pat2, ^end
1077
1078  ^pat2:
1079    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
1080
1081  ^end:
1082    pdl_interp.finalize
1083  }
1084
1085  module @rewriters {
1086    pdl_interp.func @success(%root : !pdl.operation) {
1087      %op = pdl_interp.create_operation "test.success"
1088      pdl_interp.erase %root
1089      pdl_interp.finalize
1090    }
1091  }
1092}
1093
1094// CHECK-LABEL: test.get_results_1
1095// CHECK: "test.success"
1096module @ir attributes { test.get_results_1 } {
1097  %a:5 = "test.producer"() : () -> (i32, i32, i32, i32, i32)
1098}
1099
1100// -----
1101
1102// Test all of the various combinations related to `AttrSizedResultSegments`.
1103module @patterns {
1104  pdl_interp.func @matcher(%root : !pdl.operation) {
1105    pdl_interp.check_operation_name of %root is "test.attr_sized_results" -> ^pat1, ^end
1106
1107  ^pat1:
1108    %results_0 = pdl_interp.get_results 0 of %root : !pdl.range<value>
1109    pdl_interp.is_not_null %results_0 : !pdl.range<value> -> ^pat2, ^end
1110
1111  ^pat2:
1112    %results_0_single = pdl_interp.get_results 0 of %root : !pdl.value
1113    pdl_interp.is_not_null %results_0_single : !pdl.value -> ^end, ^pat3
1114
1115  ^pat3:
1116    %results_1 = pdl_interp.get_results 1 of %root : !pdl.range<value>
1117    pdl_interp.is_not_null %results_1 : !pdl.range<value> -> ^pat4, ^end
1118
1119  ^pat4:
1120    %results_1_single = pdl_interp.get_results 1 of %root : !pdl.value
1121    pdl_interp.is_not_null %results_1_single : !pdl.value -> ^end, ^pat5
1122
1123  ^pat5:
1124    %results_2 = pdl_interp.get_results 2 of %root : !pdl.range<value>
1125    pdl_interp.is_not_null %results_2 : !pdl.range<value> -> ^pat6, ^end
1126
1127  ^pat6:
1128    %results_2_single = pdl_interp.get_results 2 of %root : !pdl.value
1129    pdl_interp.is_not_null %results_2_single : !pdl.value -> ^pat7, ^end
1130
1131  ^pat7:
1132    %invalid_results = pdl_interp.get_results 50 of %root : !pdl.value
1133    pdl_interp.is_not_null %invalid_results : !pdl.value -> ^end, ^pat8
1134
1135  ^pat8:
1136    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
1137
1138
1139  ^end:
1140    pdl_interp.finalize
1141  }
1142
1143  module @rewriters {
1144    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) {
1145      %results_0_types = pdl_interp.get_value_type of %results_0 : !pdl.range<type>
1146      %results_1_types = pdl_interp.get_value_type of %results_1 : !pdl.range<type>
1147      %results_2_types = pdl_interp.get_value_type of %results_2 : !pdl.range<type>
1148      %results_2_single_types = pdl_interp.get_value_type of %results_2_single : !pdl.type
1149
1150      %op0 = pdl_interp.create_operation "test.success" -> (%results_0_types : !pdl.range<type>)
1151      %op1 = pdl_interp.create_operation "test.success" -> (%results_1_types : !pdl.range<type>)
1152      %op2 = pdl_interp.create_operation "test.success" -> (%results_2_types : !pdl.range<type>)
1153      %op3 = pdl_interp.create_operation "test.success" -> (%results_2_single_types : !pdl.type)
1154
1155      %new_results_0 = pdl_interp.get_results of %op0 : !pdl.range<value>
1156      %new_results_1 = pdl_interp.get_results of %op1 : !pdl.range<value>
1157      %new_results_2 = pdl_interp.get_results of %op2 : !pdl.range<value>
1158
1159      pdl_interp.replace %root with (%new_results_0, %new_results_1, %new_results_2 : !pdl.range<value>, !pdl.range<value>, !pdl.range<value>)
1160      pdl_interp.finalize
1161    }
1162  }
1163}
1164
1165// CHECK-LABEL: test.get_results_2
1166// CHECK: "test.success"() : () -> ()
1167// CHECK: %[[RESULTS_1:.*]]:4 = "test.success"() : () -> (i32, i32, i32, i32)
1168// CHECK: %[[RESULTS_2:.*]] = "test.success"() : () -> i32
1169// CHECK: %[[RESULTS_2_SINGLE:.*]] = "test.success"() : () -> i32
1170// CHECK: "test.consumer"(%[[RESULTS_1]]#0, %[[RESULTS_1]]#1, %[[RESULTS_1]]#2, %[[RESULTS_1]]#3, %[[RESULTS_2]]) : (i32, i32, i32, i32, i32) -> ()
1171module @ir attributes { test.get_results_2 } {
1172  %results:5 = "test.attr_sized_results"() {result_segment_sizes = dense<[0, 4, 1, 0]> : vector<4xi32>} : () -> (i32, i32, i32, i32, i32)
1173  "test.consumer"(%results#0, %results#1, %results#2, %results#3, %results#4) : (i32, i32, i32, i32, i32) -> ()
1174}
1175
1176// -----
1177
1178//===----------------------------------------------------------------------===//
1179// pdl_interp::GetValueTypeOp
1180//===----------------------------------------------------------------------===//
1181
1182// Fully tested within the tests for other operations.
1183
1184//===----------------------------------------------------------------------===//
1185// pdl_interp::InferredTypesOp
1186//===----------------------------------------------------------------------===//
1187
1188// Fully tested within the tests for other operations.
1189
1190//===----------------------------------------------------------------------===//
1191// pdl_interp::IsNotNullOp
1192//===----------------------------------------------------------------------===//
1193
1194// Fully tested within the tests for other operations.
1195
1196//===----------------------------------------------------------------------===//
1197// pdl_interp::RecordMatchOp
1198//===----------------------------------------------------------------------===//
1199
1200// Check that the highest benefit pattern is selected.
1201module @patterns {
1202  pdl_interp.func @matcher(%root : !pdl.operation) {
1203    pdl_interp.check_operation_name of %root is "test.op" -> ^pat1, ^end
1204
1205  ^pat1:
1206    pdl_interp.record_match @rewriters::@failure(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^pat2
1207
1208  ^pat2:
1209    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(2), loc([%root]) -> ^end
1210
1211  ^end:
1212    pdl_interp.finalize
1213  }
1214
1215  module @rewriters {
1216    pdl_interp.func @failure(%root : !pdl.operation) {
1217      pdl_interp.erase %root
1218      pdl_interp.finalize
1219    }
1220    pdl_interp.func @success(%root : !pdl.operation) {
1221      %op = pdl_interp.create_operation "test.success"
1222      pdl_interp.erase %root
1223      pdl_interp.finalize
1224    }
1225  }
1226}
1227
1228// CHECK-LABEL: test.record_match_1
1229// CHECK: "test.success"
1230module @ir attributes { test.record_match_1 } {
1231  "test.op"() : () -> ()
1232}
1233
1234// -----
1235
1236// Check that ranges are properly forwarded to the result.
1237module @patterns {
1238  pdl_interp.func @matcher(%root : !pdl.operation) {
1239    pdl_interp.check_operation_name of %root is "test.op" -> ^pat1, ^end
1240
1241  ^pat1:
1242    %operands = pdl_interp.get_operands of %root : !pdl.range<value>
1243    %results = pdl_interp.get_results of %root : !pdl.range<value>
1244    %types = pdl_interp.get_value_type of %results : !pdl.range<type>
1245    pdl_interp.record_match @rewriters::@success(%operands, %types, %root : !pdl.range<value>, !pdl.range<type>, !pdl.operation) : benefit(1), loc([%root]) -> ^end
1246
1247  ^end:
1248    pdl_interp.finalize
1249  }
1250
1251  module @rewriters {
1252    pdl_interp.func @success(%operands: !pdl.range<value>, %types: !pdl.range<type>, %root: !pdl.operation) {
1253      %op = pdl_interp.create_operation "test.success"(%operands : !pdl.range<value>) -> (%types : !pdl.range<type>)
1254      %results = pdl_interp.get_results of %op : !pdl.range<value>
1255      pdl_interp.replace %root with (%results : !pdl.range<value>)
1256      pdl_interp.finalize
1257    }
1258  }
1259}
1260
1261// CHECK-LABEL: test.record_match_2
1262// CHECK: %[[OPERAND:.*]] = "test.producer"() : () -> i32
1263// CHECK: %[[RESULTS:.*]]:2 = "test.success"(%[[OPERAND]]) : (i32) -> (i64, i32)
1264// CHECK: "test.consumer"(%[[RESULTS]]#0, %[[RESULTS]]#1) : (i64, i32) -> ()
1265module @ir attributes { test.record_match_2 } {
1266  %input = "test.producer"() : () -> i32
1267  %results:2 = "test.op"(%input) : (i32) -> (i64, i32)
1268  "test.consumer"(%results#0, %results#1) : (i64, i32) -> ()
1269}
1270
1271// -----
1272
1273//===----------------------------------------------------------------------===//
1274// pdl_interp::ReplaceOp
1275//===----------------------------------------------------------------------===//
1276
1277module @patterns {
1278  pdl_interp.func @matcher(%root : !pdl.operation) {
1279    pdl_interp.check_operation_name of %root is "test.op" -> ^pat, ^end
1280
1281  ^pat:
1282    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
1283
1284  ^end:
1285    pdl_interp.finalize
1286  }
1287
1288  module @rewriters {
1289    pdl_interp.func @success(%root : !pdl.operation) {
1290      %operand = pdl_interp.get_operand 0 of %root
1291      pdl_interp.replace %root with (%operand : !pdl.value)
1292      pdl_interp.finalize
1293    }
1294  }
1295}
1296
1297// CHECK-LABEL: test.replace_op_1
1298// CHECK: %[[INPUT:.*]] = "test.op_input"
1299// CHECK-NOT: "test.op"
1300// CHECK: "test.op_consumer"(%[[INPUT]])
1301module @ir attributes { test.replace_op_1 } {
1302  %input = "test.op_input"() : () -> i32
1303  %result = "test.op"(%input) : (i32) -> i32
1304  "test.op_consumer"(%result) : (i32) -> ()
1305}
1306
1307// -----
1308
1309//===----------------------------------------------------------------------===//
1310// pdl_interp::SwitchAttributeOp
1311//===----------------------------------------------------------------------===//
1312
1313module @patterns {
1314  pdl_interp.func @matcher(%root : !pdl.operation) {
1315    %attr = pdl_interp.get_attribute "test_attr" of %root
1316    pdl_interp.switch_attribute %attr to [0, unit](^end, ^pat) -> ^end
1317
1318  ^pat:
1319    %attr_2 = pdl_interp.get_attribute "test_attr_2" of %root
1320    pdl_interp.switch_attribute %attr_2 to [0, unit](^end, ^end) -> ^pat2
1321
1322  ^pat2:
1323    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
1324
1325  ^end:
1326    pdl_interp.finalize
1327  }
1328
1329  module @rewriters {
1330    pdl_interp.func @success(%root : !pdl.operation) {
1331      %op = pdl_interp.create_operation "test.success"
1332      pdl_interp.erase %root
1333      pdl_interp.finalize
1334    }
1335  }
1336}
1337
1338// CHECK-LABEL: test.switch_attribute_1
1339// CHECK: "test.success"
1340module @ir attributes { test.switch_attribute_1 } {
1341  "test.op"() { test_attr } : () -> ()
1342}
1343
1344// -----
1345
1346//===----------------------------------------------------------------------===//
1347// pdl_interp::SwitchOperandCountOp
1348//===----------------------------------------------------------------------===//
1349
1350module @patterns {
1351  pdl_interp.func @matcher(%root : !pdl.operation) {
1352    pdl_interp.switch_operand_count of %root to dense<[0, 1]> : vector<2xi32>(^end, ^pat) -> ^end
1353
1354  ^pat:
1355    pdl_interp.switch_operand_count of %root to dense<[0, 2]> : vector<2xi32>(^end, ^end) -> ^pat2
1356
1357  ^pat2:
1358    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
1359
1360  ^end:
1361    pdl_interp.finalize
1362  }
1363
1364  module @rewriters {
1365    pdl_interp.func @success(%root : !pdl.operation) {
1366      %op = pdl_interp.create_operation "test.success"
1367      pdl_interp.erase %root
1368      pdl_interp.finalize
1369    }
1370  }
1371}
1372
1373// CHECK-LABEL: test.switch_operand_1
1374// CHECK: "test.success"
1375module @ir attributes { test.switch_operand_1 } {
1376  %input = "test.op_input"() : () -> i32
1377  "test.op"(%input) : (i32) -> ()
1378}
1379
1380// -----
1381
1382//===----------------------------------------------------------------------===//
1383// pdl_interp::SwitchOperationNameOp
1384//===----------------------------------------------------------------------===//
1385
1386module @patterns {
1387  pdl_interp.func @matcher(%root : !pdl.operation) {
1388    pdl_interp.switch_operation_name of %root to ["foo.op", "test.op"](^end, ^pat1) -> ^end
1389
1390  ^pat1:
1391    pdl_interp.switch_operation_name of %root to ["foo.op", "bar.op"](^end, ^end) -> ^pat2
1392
1393  ^pat2:
1394    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
1395
1396  ^end:
1397    pdl_interp.finalize
1398  }
1399
1400  module @rewriters {
1401    pdl_interp.func @success(%root : !pdl.operation) {
1402      %op = pdl_interp.create_operation "test.success"
1403      pdl_interp.erase %root
1404      pdl_interp.finalize
1405    }
1406  }
1407}
1408
1409// CHECK-LABEL: test.switch_operation_name_1
1410// CHECK: "test.success"
1411module @ir attributes { test.switch_operation_name_1 } {
1412  "test.op"() : () -> ()
1413}
1414
1415// -----
1416
1417//===----------------------------------------------------------------------===//
1418// pdl_interp::SwitchResultCountOp
1419//===----------------------------------------------------------------------===//
1420
1421module @patterns {
1422  pdl_interp.func @matcher(%root : !pdl.operation) {
1423    pdl_interp.switch_result_count of %root to dense<[0, 1]> : vector<2xi32>(^end, ^pat) -> ^end
1424
1425  ^pat:
1426    pdl_interp.switch_result_count of %root to dense<[0, 2]> : vector<2xi32>(^end, ^end) -> ^pat2
1427
1428  ^pat2:
1429    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
1430
1431  ^end:
1432    pdl_interp.finalize
1433  }
1434
1435  module @rewriters {
1436    pdl_interp.func @success(%root : !pdl.operation) {
1437      %op = pdl_interp.create_operation "test.success"
1438      pdl_interp.erase %root
1439      pdl_interp.finalize
1440    }
1441  }
1442}
1443
1444// CHECK-LABEL: test.switch_result_1
1445// CHECK: "test.success"
1446module @ir attributes { test.switch_result_1 } {
1447  "test.op"() : () -> i32
1448}
1449
1450// -----
1451
1452//===----------------------------------------------------------------------===//
1453// pdl_interp::SwitchTypeOp
1454//===----------------------------------------------------------------------===//
1455
1456module @patterns {
1457  pdl_interp.func @matcher(%root : !pdl.operation) {
1458    %attr = pdl_interp.get_attribute "test_attr" of %root
1459    pdl_interp.is_not_null %attr : !pdl.attribute -> ^pat1, ^end
1460
1461  ^pat1:
1462    %type = pdl_interp.get_attribute_type of %attr
1463    pdl_interp.switch_type %type to [i32, i64](^pat2, ^end) -> ^end
1464
1465  ^pat2:
1466    pdl_interp.switch_type %type to [i16, i64](^end, ^end) -> ^pat3
1467
1468  ^pat3:
1469    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
1470
1471  ^end:
1472    pdl_interp.finalize
1473  }
1474
1475  module @rewriters {
1476    pdl_interp.func @success(%root : !pdl.operation) {
1477      %op = pdl_interp.create_operation "test.success"
1478      pdl_interp.erase %root
1479      pdl_interp.finalize
1480    }
1481  }
1482}
1483
1484// CHECK-LABEL: test.switch_type_1
1485// CHECK: "test.success"
1486module @ir attributes { test.switch_type_1 } {
1487  "test.op"() { test_attr = 10 : i32 } : () -> ()
1488}
1489
1490// -----
1491
1492//===----------------------------------------------------------------------===//
1493// pdl_interp::SwitchTypesOp
1494//===----------------------------------------------------------------------===//
1495
1496module @patterns {
1497  pdl_interp.func @matcher(%root : !pdl.operation) {
1498    %results = pdl_interp.get_results of %root : !pdl.range<value>
1499    %types = pdl_interp.get_value_type of %results : !pdl.range<type>
1500    pdl_interp.switch_types %types to [[i64, i64], [i32]](^pat2, ^end) -> ^end
1501
1502  ^pat2:
1503    pdl_interp.switch_types %types to [[i32], [i64, i32]](^end, ^end) -> ^pat3
1504
1505  ^pat3:
1506    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
1507
1508  ^end:
1509    pdl_interp.finalize
1510  }
1511
1512  module @rewriters {
1513    pdl_interp.func @success(%root : !pdl.operation) {
1514      %op = pdl_interp.create_operation "test.success"
1515      pdl_interp.erase %root
1516      pdl_interp.finalize
1517    }
1518  }
1519}
1520
1521// CHECK-LABEL: test.switch_types_1
1522// CHECK: "test.success"
1523module @ir attributes { test.switch_types_1 } {
1524  %results:2 = "test.op"() : () -> (i64, i64)
1525}
1526