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