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  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    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  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    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  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    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  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    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  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    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  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    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  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    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  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    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  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    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  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    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  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    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  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    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  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    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  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    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  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    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::CreateAttributeOp
519//===----------------------------------------------------------------------===//
520
521// Fully tested within the tests for other operations.
522
523//===----------------------------------------------------------------------===//
524// pdl_interp::CreateOperationOp
525//===----------------------------------------------------------------------===//
526
527// -----
528
529//===----------------------------------------------------------------------===//
530// pdl_interp::CreateTypeOp
531//===----------------------------------------------------------------------===//
532
533module @patterns {
534  func @matcher(%root : !pdl.operation) {
535    %attr = pdl_interp.get_attribute "test_attr" of %root
536    pdl_interp.is_not_null %attr : !pdl.attribute -> ^pat1, ^end
537
538  ^pat1:
539    %test_type = pdl_interp.create_type i32
540    %type = pdl_interp.get_attribute_type of %attr
541    pdl_interp.are_equal %type, %test_type : !pdl.type -> ^pat2, ^end
542
543  ^pat2:
544    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
545
546  ^end:
547    pdl_interp.finalize
548  }
549
550  module @rewriters {
551    func @success(%root : !pdl.operation) {
552      %op = pdl_interp.create_operation "test.success"
553      pdl_interp.erase %root
554      pdl_interp.finalize
555    }
556  }
557}
558
559// CHECK-LABEL: test.create_type_1
560// CHECK: "test.success"
561module @ir attributes { test.create_type_1 } {
562  "test.op"() { test_attr = 0 : i32 } : () -> ()
563}
564
565// -----
566
567//===----------------------------------------------------------------------===//
568// pdl_interp::CreateTypesOp
569//===----------------------------------------------------------------------===//
570
571// Fully tested within the tests for other operations.
572
573//===----------------------------------------------------------------------===//
574// pdl_interp::EraseOp
575//===----------------------------------------------------------------------===//
576
577// Fully tested within the tests for other operations.
578
579//===----------------------------------------------------------------------===//
580// pdl_interp::FinalizeOp
581//===----------------------------------------------------------------------===//
582
583// Fully tested within the tests for other operations.
584
585//===----------------------------------------------------------------------===//
586// pdl_interp::GetAttributeOp
587//===----------------------------------------------------------------------===//
588
589// Fully tested within the tests for other operations.
590
591//===----------------------------------------------------------------------===//
592// pdl_interp::GetAttributeTypeOp
593//===----------------------------------------------------------------------===//
594
595// Fully tested within the tests for other operations.
596
597//===----------------------------------------------------------------------===//
598// pdl_interp::GetDefiningOpOp
599//===----------------------------------------------------------------------===//
600
601module @patterns {
602  func @matcher(%root : !pdl.operation) {
603    pdl_interp.check_operand_count of %root is 5 -> ^pat1, ^end
604
605  ^pat1:
606    %operand0 = pdl_interp.get_operand 0 of %root
607    %operand4 = pdl_interp.get_operand 4 of %root
608    %defOp0 = pdl_interp.get_defining_op of %operand0 : !pdl.value
609    %defOp4 = pdl_interp.get_defining_op of %operand4 : !pdl.value
610    pdl_interp.are_equal %defOp0, %defOp4 : !pdl.operation -> ^pat2, ^end
611
612  ^pat2:
613    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
614
615  ^end:
616    pdl_interp.finalize
617  }
618
619  module @rewriters {
620    func @success(%root : !pdl.operation) {
621      %op = pdl_interp.create_operation "test.success"
622      pdl_interp.erase %root
623      pdl_interp.finalize
624    }
625  }
626}
627
628// CHECK-LABEL: test.get_defining_op_1
629// CHECK: %[[OPERAND0:.*]] = "test.op"
630// CHECK: %[[OPERAND1:.*]] = "test.op"
631// CHECK: "test.success"
632// CHECK: "test.op"(%[[OPERAND0]], %[[OPERAND0]], %[[OPERAND0]], %[[OPERAND0]], %[[OPERAND1]])
633module @ir attributes { test.get_defining_op_1 } {
634  %operand = "test.op"() : () -> i32
635  %other_operand = "test.op"() : () -> i32
636  "test.op"(%operand, %operand, %operand, %operand, %operand) : (i32, i32, i32, i32, i32) -> ()
637  "test.op"(%operand, %operand, %operand, %operand, %other_operand) : (i32, i32, i32, i32, i32) -> ()
638}
639
640// -----
641
642//===----------------------------------------------------------------------===//
643// pdl_interp::GetOperandOp
644//===----------------------------------------------------------------------===//
645
646// Fully tested within the tests for other operations.
647
648//===----------------------------------------------------------------------===//
649// pdl_interp::GetOperandsOp
650//===----------------------------------------------------------------------===//
651
652module @patterns {
653  func @matcher(%root : !pdl.operation) {
654    pdl_interp.check_operand_count of %root is 2 -> ^pat1, ^end
655
656  ^pat1:
657    %operands = pdl_interp.get_operands 0 of %root : !pdl.range<value>
658    %full_operands = pdl_interp.get_operands of %root : !pdl.range<value>
659    pdl_interp.are_equal %operands, %full_operands : !pdl.range<value> -> ^pat2, ^end
660
661  ^pat2:
662    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
663
664  ^end:
665    pdl_interp.finalize
666  }
667
668  module @rewriters {
669    func @success(%root : !pdl.operation) {
670      %op = pdl_interp.create_operation "test.success"
671      pdl_interp.erase %root
672      pdl_interp.finalize
673    }
674  }
675}
676
677// CHECK-LABEL: test.get_operands_1
678// CHECK: "test.success"
679module @ir attributes { test.get_operands_1 } {
680  %inputs:2 = "test.producer"() : () -> (i32, i32)
681  "test.op"(%inputs#0, %inputs#1) : (i32, i32) -> ()
682}
683
684// -----
685
686// Test all of the various combinations related to `AttrSizedOperandSegments`.
687module @patterns {
688  func @matcher(%root : !pdl.operation) {
689    pdl_interp.check_operation_name of %root is "test.attr_sized_operands" -> ^pat1, ^end
690
691  ^pat1:
692    %operands_0 = pdl_interp.get_operands 0 of %root : !pdl.range<value>
693    pdl_interp.is_not_null %operands_0 : !pdl.range<value> -> ^pat2, ^end
694
695  ^pat2:
696    %operands_0_single = pdl_interp.get_operands 0 of %root : !pdl.value
697    pdl_interp.is_not_null %operands_0_single : !pdl.value -> ^end, ^pat3
698
699  ^pat3:
700    %operands_1 = pdl_interp.get_operands 1 of %root : !pdl.range<value>
701    pdl_interp.is_not_null %operands_1 : !pdl.range<value> -> ^pat4, ^end
702
703  ^pat4:
704    %operands_1_single = pdl_interp.get_operands 1 of %root : !pdl.value
705    pdl_interp.is_not_null %operands_1_single : !pdl.value -> ^end, ^pat5
706
707  ^pat5:
708    %operands_2 = pdl_interp.get_operands 2 of %root : !pdl.range<value>
709    pdl_interp.is_not_null %operands_2 : !pdl.range<value> -> ^pat6, ^end
710
711  ^pat6:
712    %operands_2_single = pdl_interp.get_operands 2 of %root : !pdl.value
713    pdl_interp.is_not_null %operands_2_single : !pdl.value -> ^pat7, ^end
714
715  ^pat7:
716    %invalid_operands = pdl_interp.get_operands 50 of %root : !pdl.value
717    pdl_interp.is_not_null %invalid_operands : !pdl.value -> ^end, ^pat8
718
719  ^pat8:
720    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
721
722
723  ^end:
724    pdl_interp.finalize
725  }
726
727  module @rewriters {
728    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) {
729      %op0 = pdl_interp.create_operation "test.success"(%operands_0 : !pdl.range<value>)
730      %op1 = pdl_interp.create_operation "test.success"(%operands_1 : !pdl.range<value>)
731      %op2 = pdl_interp.create_operation "test.success"(%operands_2 : !pdl.range<value>)
732      %op3 = pdl_interp.create_operation "test.success"(%operands_2_single : !pdl.value)
733      pdl_interp.erase %root
734      pdl_interp.finalize
735    }
736  }
737}
738
739// CHECK-LABEL: test.get_operands_2
740// CHECK-NEXT:  %[[INPUTS:.*]]:5 = "test.producer"() : () -> (i32, i32, i32, i32, i32)
741// CHECK-NEXT:  "test.success"() : () -> ()
742// CHECK-NEXT:  "test.success"(%[[INPUTS]]#0, %[[INPUTS]]#1, %[[INPUTS]]#2, %[[INPUTS]]#3) : (i32, i32, i32, i32) -> ()
743// CHECK-NEXT:  "test.success"(%[[INPUTS]]#4) : (i32) -> ()
744// CHECK-NEXT:  "test.success"(%[[INPUTS]]#4) : (i32) -> ()
745module @ir attributes { test.get_operands_2 } {
746  %inputs:5 = "test.producer"() : () -> (i32, i32, i32, i32, i32)
747  "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) -> ()
748}
749
750// -----
751
752//===----------------------------------------------------------------------===//
753// pdl_interp::GetResultOp
754//===----------------------------------------------------------------------===//
755
756module @patterns {
757  func @matcher(%root : !pdl.operation) {
758    pdl_interp.check_result_count of %root is 5 -> ^pat1, ^end
759
760  ^pat1:
761    %result0 = pdl_interp.get_result 0 of %root
762    %result4 = pdl_interp.get_result 4 of %root
763    %result0_type = pdl_interp.get_value_type of %result0 : !pdl.type
764    %result4_type = pdl_interp.get_value_type of %result4 : !pdl.type
765    pdl_interp.are_equal %result0_type, %result4_type : !pdl.type -> ^pat2, ^end
766
767  ^pat2:
768    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
769
770  ^end:
771    pdl_interp.finalize
772  }
773
774  module @rewriters {
775    func @success(%root : !pdl.operation) {
776      %op = pdl_interp.create_operation "test.success"
777      pdl_interp.erase %root
778      pdl_interp.finalize
779    }
780  }
781}
782
783// CHECK-LABEL: test.get_result_1
784// CHECK: "test.success"
785// CHECK: "test.op"() : () -> (i32, i32, i32, i32, i64)
786module @ir attributes { test.get_result_1 } {
787  %a:5 = "test.op"() : () -> (i32, i32, i32, i32, i32)
788  %b:5 = "test.op"() : () -> (i32, i32, i32, i32, i64)
789}
790
791// -----
792
793//===----------------------------------------------------------------------===//
794// pdl_interp::GetResultsOp
795//===----------------------------------------------------------------------===//
796
797module @patterns {
798  func @matcher(%root : !pdl.operation) {
799    pdl_interp.check_result_count of %root is 5 -> ^pat1, ^end
800
801  ^pat1:
802    %results = pdl_interp.get_results 0 of %root : !pdl.range<value>
803    %full_results = pdl_interp.get_results of %root : !pdl.range<value>
804    pdl_interp.are_equal %results, %full_results : !pdl.range<value> -> ^pat2, ^end
805
806  ^pat2:
807    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
808
809  ^end:
810    pdl_interp.finalize
811  }
812
813  module @rewriters {
814    func @success(%root : !pdl.operation) {
815      %op = pdl_interp.create_operation "test.success"
816      pdl_interp.erase %root
817      pdl_interp.finalize
818    }
819  }
820}
821
822// CHECK-LABEL: test.get_results_1
823// CHECK: "test.success"
824module @ir attributes { test.get_results_1 } {
825  %a:5 = "test.producer"() : () -> (i32, i32, i32, i32, i32)
826}
827
828// -----
829
830// Test all of the various combinations related to `AttrSizedResultSegments`.
831module @patterns {
832  func @matcher(%root : !pdl.operation) {
833    pdl_interp.check_operation_name of %root is "test.attr_sized_results" -> ^pat1, ^end
834
835  ^pat1:
836    %results_0 = pdl_interp.get_results 0 of %root : !pdl.range<value>
837    pdl_interp.is_not_null %results_0 : !pdl.range<value> -> ^pat2, ^end
838
839  ^pat2:
840    %results_0_single = pdl_interp.get_results 0 of %root : !pdl.value
841    pdl_interp.is_not_null %results_0_single : !pdl.value -> ^end, ^pat3
842
843  ^pat3:
844    %results_1 = pdl_interp.get_results 1 of %root : !pdl.range<value>
845    pdl_interp.is_not_null %results_1 : !pdl.range<value> -> ^pat4, ^end
846
847  ^pat4:
848    %results_1_single = pdl_interp.get_results 1 of %root : !pdl.value
849    pdl_interp.is_not_null %results_1_single : !pdl.value -> ^end, ^pat5
850
851  ^pat5:
852    %results_2 = pdl_interp.get_results 2 of %root : !pdl.range<value>
853    pdl_interp.is_not_null %results_2 : !pdl.range<value> -> ^pat6, ^end
854
855  ^pat6:
856    %results_2_single = pdl_interp.get_results 2 of %root : !pdl.value
857    pdl_interp.is_not_null %results_2_single : !pdl.value -> ^pat7, ^end
858
859  ^pat7:
860    %invalid_results = pdl_interp.get_results 50 of %root : !pdl.value
861    pdl_interp.is_not_null %invalid_results : !pdl.value -> ^end, ^pat8
862
863  ^pat8:
864    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
865
866
867  ^end:
868    pdl_interp.finalize
869  }
870
871  module @rewriters {
872    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) {
873      %results_0_types = pdl_interp.get_value_type of %results_0 : !pdl.range<type>
874      %results_1_types = pdl_interp.get_value_type of %results_1 : !pdl.range<type>
875      %results_2_types = pdl_interp.get_value_type of %results_2 : !pdl.range<type>
876      %results_2_single_types = pdl_interp.get_value_type of %results_2_single : !pdl.type
877
878      %op0 = pdl_interp.create_operation "test.success" -> (%results_0_types : !pdl.range<type>)
879      %op1 = pdl_interp.create_operation "test.success" -> (%results_1_types : !pdl.range<type>)
880      %op2 = pdl_interp.create_operation "test.success" -> (%results_2_types : !pdl.range<type>)
881      %op3 = pdl_interp.create_operation "test.success" -> (%results_2_single_types : !pdl.type)
882
883      %new_results_0 = pdl_interp.get_results of %op0 : !pdl.range<value>
884      %new_results_1 = pdl_interp.get_results of %op1 : !pdl.range<value>
885      %new_results_2 = pdl_interp.get_results of %op2 : !pdl.range<value>
886
887      pdl_interp.replace %root with (%new_results_0, %new_results_1, %new_results_2 : !pdl.range<value>, !pdl.range<value>, !pdl.range<value>)
888      pdl_interp.finalize
889    }
890  }
891}
892
893// CHECK-LABEL: test.get_results_2
894// CHECK: "test.success"() : () -> ()
895// CHECK: %[[RESULTS_1:.*]]:4 = "test.success"() : () -> (i32, i32, i32, i32)
896// CHECK: %[[RESULTS_2:.*]] = "test.success"() : () -> i32
897// CHECK: %[[RESULTS_2_SINGLE:.*]] = "test.success"() : () -> i32
898// CHECK: "test.consumer"(%[[RESULTS_1]]#0, %[[RESULTS_1]]#1, %[[RESULTS_1]]#2, %[[RESULTS_1]]#3, %[[RESULTS_2]]) : (i32, i32, i32, i32, i32) -> ()
899module @ir attributes { test.get_results_2 } {
900  %results:5 = "test.attr_sized_results"() {result_segment_sizes = dense<[0, 4, 1, 0]> : vector<4xi32>} : () -> (i32, i32, i32, i32, i32)
901  "test.consumer"(%results#0, %results#1, %results#2, %results#3, %results#4) : (i32, i32, i32, i32, i32) -> ()
902}
903
904// -----
905
906//===----------------------------------------------------------------------===//
907// pdl_interp::GetValueTypeOp
908//===----------------------------------------------------------------------===//
909
910// Fully tested within the tests for other operations.
911
912//===----------------------------------------------------------------------===//
913// pdl_interp::InferredTypesOp
914//===----------------------------------------------------------------------===//
915
916// Fully tested within the tests for other operations.
917
918//===----------------------------------------------------------------------===//
919// pdl_interp::IsNotNullOp
920//===----------------------------------------------------------------------===//
921
922// Fully tested within the tests for other operations.
923
924//===----------------------------------------------------------------------===//
925// pdl_interp::RecordMatchOp
926//===----------------------------------------------------------------------===//
927
928// Check that the highest benefit pattern is selected.
929module @patterns {
930  func @matcher(%root : !pdl.operation) {
931    pdl_interp.check_operation_name of %root is "test.op" -> ^pat1, ^end
932
933  ^pat1:
934    pdl_interp.record_match @rewriters::@failure(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^pat2
935
936  ^pat2:
937    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(2), loc([%root]) -> ^end
938
939  ^end:
940    pdl_interp.finalize
941  }
942
943  module @rewriters {
944    func @failure(%root : !pdl.operation) {
945      pdl_interp.erase %root
946      pdl_interp.finalize
947    }
948    func @success(%root : !pdl.operation) {
949      %op = pdl_interp.create_operation "test.success"
950      pdl_interp.erase %root
951      pdl_interp.finalize
952    }
953  }
954}
955
956// CHECK-LABEL: test.record_match_1
957// CHECK: "test.success"
958module @ir attributes { test.record_match_1 } {
959  "test.op"() : () -> ()
960}
961
962// -----
963
964// Check that ranges are properly forwarded to the result.
965module @patterns {
966  func @matcher(%root : !pdl.operation) {
967    pdl_interp.check_operation_name of %root is "test.op" -> ^pat1, ^end
968
969  ^pat1:
970    %operands = pdl_interp.get_operands of %root : !pdl.range<value>
971    %results = pdl_interp.get_results of %root : !pdl.range<value>
972    %types = pdl_interp.get_value_type of %results : !pdl.range<type>
973    pdl_interp.record_match @rewriters::@success(%operands, %types, %root : !pdl.range<value>, !pdl.range<type>, !pdl.operation) : benefit(1), loc([%root]) -> ^end
974
975  ^end:
976    pdl_interp.finalize
977  }
978
979  module @rewriters {
980    func @success(%operands: !pdl.range<value>, %types: !pdl.range<type>, %root: !pdl.operation) {
981      %op = pdl_interp.create_operation "test.success"(%operands : !pdl.range<value>) -> (%types : !pdl.range<type>)
982      %results = pdl_interp.get_results of %op : !pdl.range<value>
983      pdl_interp.replace %root with (%results : !pdl.range<value>)
984      pdl_interp.finalize
985    }
986  }
987}
988
989// CHECK-LABEL: test.record_match_2
990// CHECK: %[[OPERAND:.*]] = "test.producer"() : () -> i32
991// CHECK: %[[RESULTS:.*]]:2 = "test.success"(%[[OPERAND]]) : (i32) -> (i64, i32)
992// CHECK: "test.consumer"(%[[RESULTS]]#0, %[[RESULTS]]#1) : (i64, i32) -> ()
993module @ir attributes { test.record_match_2 } {
994  %input = "test.producer"() : () -> i32
995  %results:2 = "test.op"(%input) : (i32) -> (i64, i32)
996  "test.consumer"(%results#0, %results#1) : (i64, i32) -> ()
997}
998
999// -----
1000
1001//===----------------------------------------------------------------------===//
1002// pdl_interp::ReplaceOp
1003//===----------------------------------------------------------------------===//
1004
1005module @patterns {
1006  func @matcher(%root : !pdl.operation) {
1007    pdl_interp.check_operation_name of %root is "test.op" -> ^pat, ^end
1008
1009  ^pat:
1010    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
1011
1012  ^end:
1013    pdl_interp.finalize
1014  }
1015
1016  module @rewriters {
1017    func @success(%root : !pdl.operation) {
1018      %operand = pdl_interp.get_operand 0 of %root
1019      pdl_interp.replace %root with (%operand : !pdl.value)
1020      pdl_interp.finalize
1021    }
1022  }
1023}
1024
1025// CHECK-LABEL: test.replace_op_1
1026// CHECK: %[[INPUT:.*]] = "test.op_input"
1027// CHECK-NOT: "test.op"
1028// CHECK: "test.op_consumer"(%[[INPUT]])
1029module @ir attributes { test.replace_op_1 } {
1030  %input = "test.op_input"() : () -> i32
1031  %result = "test.op"(%input) : (i32) -> i32
1032  "test.op_consumer"(%result) : (i32) -> ()
1033}
1034
1035// -----
1036
1037//===----------------------------------------------------------------------===//
1038// pdl_interp::SwitchAttributeOp
1039//===----------------------------------------------------------------------===//
1040
1041module @patterns {
1042  func @matcher(%root : !pdl.operation) {
1043    %attr = pdl_interp.get_attribute "test_attr" of %root
1044    pdl_interp.switch_attribute %attr to [0, unit](^end, ^pat) -> ^end
1045
1046  ^pat:
1047    %attr_2 = pdl_interp.get_attribute "test_attr_2" of %root
1048    pdl_interp.switch_attribute %attr_2 to [0, unit](^end, ^end) -> ^pat2
1049
1050  ^pat2:
1051    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
1052
1053  ^end:
1054    pdl_interp.finalize
1055  }
1056
1057  module @rewriters {
1058    func @success(%root : !pdl.operation) {
1059      %op = pdl_interp.create_operation "test.success"
1060      pdl_interp.erase %root
1061      pdl_interp.finalize
1062    }
1063  }
1064}
1065
1066// CHECK-LABEL: test.switch_attribute_1
1067// CHECK: "test.success"
1068module @ir attributes { test.switch_attribute_1 } {
1069  "test.op"() { test_attr } : () -> ()
1070}
1071
1072// -----
1073
1074//===----------------------------------------------------------------------===//
1075// pdl_interp::SwitchOperandCountOp
1076//===----------------------------------------------------------------------===//
1077
1078module @patterns {
1079  func @matcher(%root : !pdl.operation) {
1080    pdl_interp.switch_operand_count of %root to dense<[0, 1]> : vector<2xi32>(^end, ^pat) -> ^end
1081
1082  ^pat:
1083    pdl_interp.switch_operand_count of %root to dense<[0, 2]> : vector<2xi32>(^end, ^end) -> ^pat2
1084
1085  ^pat2:
1086    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
1087
1088  ^end:
1089    pdl_interp.finalize
1090  }
1091
1092  module @rewriters {
1093    func @success(%root : !pdl.operation) {
1094      %op = pdl_interp.create_operation "test.success"
1095      pdl_interp.erase %root
1096      pdl_interp.finalize
1097    }
1098  }
1099}
1100
1101// CHECK-LABEL: test.switch_operand_1
1102// CHECK: "test.success"
1103module @ir attributes { test.switch_operand_1 } {
1104  %input = "test.op_input"() : () -> i32
1105  "test.op"(%input) : (i32) -> ()
1106}
1107
1108// -----
1109
1110//===----------------------------------------------------------------------===//
1111// pdl_interp::SwitchOperationNameOp
1112//===----------------------------------------------------------------------===//
1113
1114module @patterns {
1115  func @matcher(%root : !pdl.operation) {
1116    pdl_interp.switch_operation_name of %root to ["foo.op", "test.op"](^end, ^pat1) -> ^end
1117
1118  ^pat1:
1119    pdl_interp.switch_operation_name of %root to ["foo.op", "bar.op"](^end, ^end) -> ^pat2
1120
1121  ^pat2:
1122    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
1123
1124  ^end:
1125    pdl_interp.finalize
1126  }
1127
1128  module @rewriters {
1129    func @success(%root : !pdl.operation) {
1130      %op = pdl_interp.create_operation "test.success"
1131      pdl_interp.erase %root
1132      pdl_interp.finalize
1133    }
1134  }
1135}
1136
1137// CHECK-LABEL: test.switch_operation_name_1
1138// CHECK: "test.success"
1139module @ir attributes { test.switch_operation_name_1 } {
1140  "test.op"() : () -> ()
1141}
1142
1143// -----
1144
1145//===----------------------------------------------------------------------===//
1146// pdl_interp::SwitchResultCountOp
1147//===----------------------------------------------------------------------===//
1148
1149module @patterns {
1150  func @matcher(%root : !pdl.operation) {
1151    pdl_interp.switch_result_count of %root to dense<[0, 1]> : vector<2xi32>(^end, ^pat) -> ^end
1152
1153  ^pat:
1154    pdl_interp.switch_result_count of %root to dense<[0, 2]> : vector<2xi32>(^end, ^end) -> ^pat2
1155
1156  ^pat2:
1157    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
1158
1159  ^end:
1160    pdl_interp.finalize
1161  }
1162
1163  module @rewriters {
1164    func @success(%root : !pdl.operation) {
1165      %op = pdl_interp.create_operation "test.success"
1166      pdl_interp.erase %root
1167      pdl_interp.finalize
1168    }
1169  }
1170}
1171
1172// CHECK-LABEL: test.switch_result_1
1173// CHECK: "test.success"
1174module @ir attributes { test.switch_result_1 } {
1175  "test.op"() : () -> i32
1176}
1177
1178// -----
1179
1180//===----------------------------------------------------------------------===//
1181// pdl_interp::SwitchTypeOp
1182//===----------------------------------------------------------------------===//
1183
1184module @patterns {
1185  func @matcher(%root : !pdl.operation) {
1186    %attr = pdl_interp.get_attribute "test_attr" of %root
1187    pdl_interp.is_not_null %attr : !pdl.attribute -> ^pat1, ^end
1188
1189  ^pat1:
1190    %type = pdl_interp.get_attribute_type of %attr
1191    pdl_interp.switch_type %type to [i32, i64](^pat2, ^end) -> ^end
1192
1193  ^pat2:
1194    pdl_interp.switch_type %type to [i16, i64](^end, ^end) -> ^pat3
1195
1196  ^pat3:
1197    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
1198
1199  ^end:
1200    pdl_interp.finalize
1201  }
1202
1203  module @rewriters {
1204    func @success(%root : !pdl.operation) {
1205      %op = pdl_interp.create_operation "test.success"
1206      pdl_interp.erase %root
1207      pdl_interp.finalize
1208    }
1209  }
1210}
1211
1212// CHECK-LABEL: test.switch_type_1
1213// CHECK: "test.success"
1214module @ir attributes { test.switch_type_1 } {
1215  "test.op"() { test_attr = 10 : i32 } : () -> ()
1216}
1217
1218// -----
1219
1220//===----------------------------------------------------------------------===//
1221// pdl_interp::SwitchTypesOp
1222//===----------------------------------------------------------------------===//
1223
1224module @patterns {
1225  func @matcher(%root : !pdl.operation) {
1226    %results = pdl_interp.get_results of %root : !pdl.range<value>
1227    %types = pdl_interp.get_value_type of %results : !pdl.range<type>
1228    pdl_interp.switch_types %types to [[i64, i64], [i32]](^pat2, ^end) -> ^end
1229
1230  ^pat2:
1231    pdl_interp.switch_types %types to [[i32], [i64, i32]](^end, ^end) -> ^pat3
1232
1233  ^pat3:
1234    pdl_interp.record_match @rewriters::@success(%root : !pdl.operation) : benefit(1), loc([%root]) -> ^end
1235
1236  ^end:
1237    pdl_interp.finalize
1238  }
1239
1240  module @rewriters {
1241    func @success(%root : !pdl.operation) {
1242      %op = pdl_interp.create_operation "test.success"
1243      pdl_interp.erase %root
1244      pdl_interp.finalize
1245    }
1246  }
1247}
1248
1249// CHECK-LABEL: test.switch_types_1
1250// CHECK: "test.success"
1251module @ir attributes { test.switch_types_1 } {
1252  %results:2 = "test.op"() : () -> (i64, i64)
1253}
1254