Fix GCC build problem with 288f05f related to SmallVector. (#116958)
[llvm-project.git] / mlir / test / mlir-tblgen / pattern.mlir
blob60d46e676d2a33ae9ea34b6086fdb5dcfba1c986
1 // RUN: mlir-opt -test-greedy-patterns -mlir-print-debuginfo -mlir-print-local-scope %s | FileCheck %s
3 // CHECK-LABEL: verifyFusedLocs
4 func.func @verifyFusedLocs(%arg0 : i32) -> i32 {
5   %0 = "test.op_a"(%arg0) {attr = 10 : i32} : (i32) -> i32 loc("a")
6   %result = "test.op_a"(%0) {attr = 20 : i32} : (i32) -> i32 loc("b")
8   // CHECK: "test.op_b"(%arg0) <{attr = 10 : i32}> : (i32) -> i32 loc("a")
9   // CHECK: "test.op_b"(%arg0) <{attr = 20 : i32}> : (i32) -> i32 loc(fused["b", "a"])
10   return %result : i32
13 // CHECK-LABEL: verifyDesignatedLoc
14 func.func @verifyDesignatedLoc(%arg0 : i32) -> i32 {
15   %0 = "test.loc_src"(%arg0) : (i32) -> i32 loc("loc3")
16   %1 = "test.loc_src"(%0) : (i32) -> i32 loc("loc2")
17   %2 = "test.loc_src"(%1) : (i32) -> i32 loc("loc1")
18   "test.loc_src_no_res"(%2) : (i32) -> () loc("loc4")
20   // CHECK: "test.loc_dst"({{.*}}) : (i32) -> i32 loc("loc1")
21   // CHECK: "test.loc_dst"({{.*}}) : (i32) -> i32 loc("named")
22   // CHECK: "test.loc_dst"({{.*}}) : (i32) -> i32 loc(fused<"fused">["loc2", "loc3"])
23   // CHECK: "test.loc_dst_no_res"({{.*}}) : (i32) -> () loc("loc4")
24   return %1 : i32
27 // CHECK-LABEL: verifyZeroResult
28 func.func @verifyZeroResult(%arg0 : i32) {
29   // CHECK: "test.op_i"(%arg0) : (i32) -> ()
30   "test.op_h"(%arg0) : (i32) -> ()
31   return
34 // CHECK-LABEL: verifyZeroArg
35 func.func @verifyZeroArg() -> i32 {
36   // CHECK: "test.op_k"() : () -> i32
37   %0 = "test.op_j"() : () -> i32
38   return %0 : i32
41 // CHECK-LABEL: testIgnoreArgMatch
42 // CHECK-SAME: (%{{[a-z0-9]*}}: i32 loc({{[^)]*}}), %[[ARG1:[a-z0-9]*]]: i32 loc({{[^)]*}}),
43 func.func @testIgnoreArgMatch(%arg0: i32, %arg1: i32, %arg2: i32, %arg3: f32) {
44   // CHECK: "test.ignore_arg_match_dst"(%[[ARG1]]) <{f = 15 : i64}>
45   "test.ignore_arg_match_src"(%arg0, %arg1, %arg2) {d = 42, e = 24, f = 15} : (i32, i32, i32) -> ()
47   // CHECK: test.ignore_arg_match_src
48   // Not match because wrong type for $c.
49   "test.ignore_arg_match_src"(%arg0, %arg1, %arg3) {d = 42, e = 24, f = 15} : (i32, i32, f32) -> ()
51   // CHECK: test.ignore_arg_match_src
52   // Not match because wrong type for $f.
53   "test.ignore_arg_match_src"(%arg0, %arg1, %arg2) {d = 42 : i32, e = 24, f = 15} : (i32, i32, i32) -> ()
54   return
57 // CHECK-LABEL: verifyInterleavedOperandAttribute
58 // CHECK-SAME:    %[[ARG0:.*]]: i32 loc({{[^)]*}}), %[[ARG1:.*]]: i32 loc({{[^)]*}})
59 func.func @verifyInterleavedOperandAttribute(%arg0: i32, %arg1: i32) {
60   // CHECK: "test.interleaved_operand_attr2"(%[[ARG0]], %[[ARG1]]) <{attr1 = 15 : i64, attr2 = 42 : i64}>
61   "test.interleaved_operand_attr1"(%arg0, %arg1) {attr1 = 15, attr2 = 42} : (i32, i32) -> ()
62   return
65 // CHECK-LABEL: verifyBenefit
66 func.func @verifyBenefit(%arg0 : i32) -> i32 {
67   %0 = "test.op_d"(%arg0) : (i32) -> i32
68   %1 = "test.op_g"(%arg0) : (i32) -> i32
69   %2 = "test.op_g"(%1) : (i32) -> i32
71   // CHECK: "test.op_f"(%arg0)
72   // CHECK: "test.op_b"(%arg0) <{attr = 34 : i32}>
73   return %0 : i32
76 // CHECK-LABEL: verifyNativeCodeCall
77 func.func @verifyNativeCodeCall(%arg0: i32, %arg1: i32) -> (i32, i32) {
78   // CHECK: %0 = "test.native_code_call2"(%arg0) <{attr = [42, 24]}> : (i32) -> i32
79   // CHECK:  return %0, %arg1
80   %0 = "test.native_code_call1"(%arg0, %arg1) {choice = true, attr1 = 42, attr2 = 24} : (i32, i32) -> (i32)
81   %1 = "test.native_code_call1"(%arg0, %arg1) {choice = false, attr1 = 42, attr2 = 24} : (i32, i32) -> (i32)
82   return %0, %1: i32, i32
85 // CHECK-LABEL: verifyAuxiliaryNativeCodeCall
86 func.func @verifyAuxiliaryNativeCodeCall(%arg0: i32) -> (i32) {
87   // CHECK: test.op_i
88   // CHECK: test.op_k
89   %0 = "test.native_code_call3"(%arg0) : (i32) -> (i32)
90   return %0 : i32
93 // CHECK-LABEL: verifyNativeCodeCallBinding
94 func.func @verifyNativeCodeCallBinding(%arg0 : i32) -> (i32) {
95   %0 = "test.op_k"() : () -> (i32)
96   // CHECK: %[[A:.*]], %[[B:.*]] = "test.native_code_call5"(%1, %1) : (i32, i32) -> (i32, i32)
97   %1, %2 = "test.native_code_call4"(%0) : (i32) -> (i32, i32)
98   %3 = "test.constant"() {value = 1 : i8} : () -> i8
99   // %3 is i8 so it'll fail at GetFirstI32Result match. The operation should
100   // keep the same form.
101   // CHECK: %{{.*}}, %{{.*}} = "test.native_code_call4"({{%.*}}) : (i8) -> (i32, i32)
102   %4, %5 = "test.native_code_call4"(%3) : (i8) -> (i32, i32)
103   // CHECK: return %[[A]]
104   return %1 : i32
107 // CHECK-LABEL: verifyMultipleNativeCodeCallBinding
108 func.func @verifyMultipleNativeCodeCallBinding(%arg0 : i32) -> (i32) {
109   %0 = "test.op_k"() : () -> (i32)
110   %1 = "test.op_k"() : () -> (i32)
111   // CHECK: %[[A:.*]] = "test.native_code_call7"(%1) : (i32) -> i32
112   // CHECK: %[[A:.*]] = "test.native_code_call7"(%0) : (i32) -> i32
113   %2, %3 = "test.native_code_call6"(%0, %1) : (i32, i32) -> (i32, i32)
114   return %2 : i32
117 // CHECK-LABEL: verifyAllAttrConstraintOf
118 func.func @verifyAllAttrConstraintOf() -> (i32, i32, i32) {
119   // CHECK: "test.all_attr_constraint_of2"
120   %0 = "test.all_attr_constraint_of1"() {attr = [0, 1]} : () -> (i32)
121   // CHECK: "test.all_attr_constraint_of1"
122   %1 = "test.all_attr_constraint_of1"() {attr = [0, 2]} : () -> (i32)
123   // CHECK: "test.all_attr_constraint_of1"
124   %2 = "test.all_attr_constraint_of1"() {attr = [-1, 1]} : () -> (i32)
125   return %0, %1, %2: i32, i32, i32
128 // CHECK-LABEL: verifyManyArgs
129 // CHECK-SAME: (%[[ARG:.*]]: i32 loc({{[^)]*}}))
130 func.func @verifyManyArgs(%arg: i32) {
131   // CHECK: "test.many_arguments"(%[[ARG]], %[[ARG]], %[[ARG]], %[[ARG]], %[[ARG]], %[[ARG]], %[[ARG]], %[[ARG]], %[[ARG]])
132   // CHECK-SAME: {attr1 = 24 : i64, attr2 = 42 : i64, attr3 = 42 : i64, attr4 = 42 : i64, attr5 = 42 : i64, attr6 = 42 : i64, attr7 = 42 : i64, attr8 = 42 : i64, attr9 = 42 : i64}
133   "test.many_arguments"(%arg, %arg, %arg, %arg, %arg, %arg, %arg, %arg, %arg) {
134     attr1 = 42, attr2 = 42, attr3 = 42, attr4 = 42, attr5 = 42,
135     attr6 = 42, attr7 = 42, attr8 = 42, attr9 = 42
136   } : (i32, i32, i32, i32, i32, i32, i32, i32, i32) -> ()
137   return
140 // CHECK-LABEL: verifyEqualArgs
141 func.func @verifyEqualArgs(%arg0: i32, %arg1: i32) {
142   // def TestEqualArgsPattern : Pat<(OpN $a, $a), (OpO $a)>;
144   // CHECK: "test.op_o"(%arg0) : (i32) -> i32
145   "test.op_n"(%arg0, %arg0) : (i32, i32) -> (i32)
147   // CHECK: "test.op_n"(%arg0, %arg1) : (i32, i32) -> i32
148   "test.op_n"(%arg0, %arg1) : (i32, i32) -> (i32)
150   return
153 // CHECK-LABEL: verifyNestedOpEqualArgs
154 func.func @verifyNestedOpEqualArgs(
155   %arg0: i32, %arg1: i32, %arg2 : i32, %arg3 : i32, %arg4 : i32, %arg5 : i32) {
156   // def TestNestedOpEqualArgsPattern :
157   //   Pat<(OpN $b, (OpP $a, $b, $c, $d, $e, $f)), (replaceWithValue $b)>;
159   // CHECK: %arg1
160   %0 = "test.op_p"(%arg0, %arg1, %arg2, %arg3, %arg4, %arg5)
161     : (i32, i32, i32, i32, i32, i32) -> (i32)
162   %1 = "test.op_n"(%arg1, %0) : (i32, i32) -> (i32)
164   // CHECK: test.op_p
165   // CHECK: test.op_n
166   %2 = "test.op_p"(%arg0, %arg1, %arg2, %arg3, %arg4, %arg5)
167     : (i32, i32, i32, i32, i32, i32) -> (i32)
168   %3 = "test.op_n"(%arg0, %2) : (i32, i32) -> (i32)
170   return
173 // CHECK-LABEL: verifyNestedSameOpAndSameArgEquality
174 func.func @verifyNestedSameOpAndSameArgEquality(%arg0: i32, %arg1: i32) -> i32 {
175   // def TestNestedSameOpAndSameArgEqualityPattern:
176   //   Pat<(OpN (OpN $_, $x), $x), (replaceWithValue $x)>;
178   %0 = "test.op_n"(%arg1, %arg0) : (i32, i32) -> (i32)
179   %1 = "test.op_n"(%0, %arg0) : (i32, i32) -> (i32)
180   // CHECK: return %arg0 : i32
181   return %1 : i32
184 // CHECK-LABEL: verifyMultipleEqualArgs
185 func.func @verifyMultipleEqualArgs(
186   %arg0: i32, %arg1 : i32, %arg2 : i32, %arg3 : i32, %arg4 : i32) {
187   // def TestMultipleEqualArgsPattern :
188   //   Pat<(OpP $a, $b, $a, $a, $b, $c), (OpN $c, $b)>;
190   // CHECK: "test.op_n"(%arg2, %arg1) : (i32, i32) -> i32
191   "test.op_p"(%arg0, %arg1, %arg0, %arg0, %arg1, %arg2) :
192     (i32, i32, i32, i32 , i32, i32) -> i32
194   // CHECK: test.op_p
195   "test.op_p"(%arg0, %arg1, %arg0, %arg0, %arg0, %arg2) :
196     (i32, i32, i32, i32 , i32, i32) -> i32
198   // CHECK: test.op_p
199   "test.op_p"(%arg0, %arg1, %arg1, %arg0, %arg1, %arg2) :
200     (i32, i32, i32, i32 , i32, i32) -> i32
202    // CHECK: test.op_p
203   "test.op_p"(%arg0, %arg1, %arg2, %arg2, %arg3, %arg4) :
204     (i32, i32, i32, i32 , i32, i32) -> i32
206   return
209 //===----------------------------------------------------------------------===//
210 // Test Symbol Binding
211 //===----------------------------------------------------------------------===//
213 // CHECK-LABEL: symbolBinding
214 func.func @symbolBinding(%arg0: i32) -> i32 {
215   // An op with one use is matched.
216   // CHECK: %0 = "test.symbol_binding_b"(%arg0)
217   // CHECK: %1 = "test.symbol_binding_c"(%0)
218   // CHECK: %2 = "test.symbol_binding_d"(%0, %1) <{attr = 42 : i64}>
219   %0 = "test.symbol_binding_a"(%arg0) {attr = 42} : (i32) -> (i32)
221   // An op without any use is not matched.
222   // CHECK: "test.symbol_binding_a"(%arg0)
223   %1 = "test.symbol_binding_a"(%arg0) {attr = 42} : (i32) -> (i32)
225   // CHECK: return %2
226   return %0: i32
229 // CHECK-LABEL: symbolBindingNoResult
230 func.func @symbolBindingNoResult(%arg0: i32) {
231   // CHECK: test.symbol_binding_b
232   "test.symbol_binding_no_result"(%arg0) : (i32) -> ()
233   return
236 //===----------------------------------------------------------------------===//
237 // Test Attributes
238 //===----------------------------------------------------------------------===//
240 // CHECK-LABEL: succeedMatchOpAttr
241 func.func @succeedMatchOpAttr() -> i32 {
242   // CHECK: "test.match_op_attribute2"() <{default_valued_attr = 3 : i32, more_attr = 4 : i32, optional_attr = 2 : i32, required_attr = 1 : i32}>
243   %0 = "test.match_op_attribute1"() {required_attr = 1: i32, optional_attr = 2: i32, default_valued_attr = 3: i32, more_attr = 4: i32} : () -> (i32)
244   return %0: i32
247 // CHECK-LABEL: succeedMatchMissingOptionalAttr
248 func.func @succeedMatchMissingOptionalAttr() -> i32 {
249   // CHECK: "test.match_op_attribute2"() <{default_valued_attr = 3 : i32, more_attr = 4 : i32, required_attr = 1 : i32}>
250   %0 = "test.match_op_attribute1"() {required_attr = 1: i32, default_valued_attr = 3: i32, more_attr = 4: i32} : () -> (i32)
251   return %0: i32
254 // CHECK-LABEL: succeedMatchMissingDefaultValuedAttr
255 func.func @succeedMatchMissingDefaultValuedAttr() -> i32 {
256   // CHECK: "test.match_op_attribute2"() <{default_valued_attr = 42 : i32, more_attr = 4 : i32, optional_attr = 2 : i32, required_attr = 1 : i32}>
257   %0 = "test.match_op_attribute1"() {required_attr = 1: i32, optional_attr = 2: i32, more_attr = 4: i32} : () -> (i32)
258   return %0: i32
261 // CHECK-LABEL: failedMatchAdditionalConstraintNotSatisfied
262 func.func @failedMatchAdditionalConstraintNotSatisfied() -> i32 {
263   // CHECK: "test.match_op_attribute1"()
264   %0 = "test.match_op_attribute1"() {required_attr = 1: i32, optional_attr = 2: i32, more_attr = 5: i32} : () -> (i32)
265   return %0: i32
268 // CHECK-LABEL: verifyConstantAttr
269 func.func @verifyConstantAttr(%arg0 : i32) -> i32 {
270   // CHECK: "test.op_b"(%arg0) <{attr = 17 : i32}> : (i32) -> i32 loc("a")
271   %0 = "test.op_c"(%arg0) : (i32) -> i32 loc("a")
272   return %0 : i32
275 // CHECK-LABEL: verifyUnitAttr
276 func.func @verifyUnitAttr() -> (i32, i32) {
277   // Unit attribute present in the matched op is propagated as attr2.
278   // CHECK: "test.match_op_attribute4"() <{attr1, attr2}> : () -> i32
279   %0 = "test.match_op_attribute3"() {attr} : () -> i32
281   // Since the original op doesn't have the unit attribute, the new op
282   // only has the constant-constructed unit attribute attr1.
283   // CHECK: "test.match_op_attribute4"() <{attr1}> : () -> i32
284   %1 = "test.match_op_attribute3"() : () -> i32
285   return %0, %1 : i32, i32
288 //===----------------------------------------------------------------------===//
289 // Test Constant Matching
290 //===----------------------------------------------------------------------===//
292 // CHECK-LABEL: testConstOp
293 func.func @testConstOp() -> (i32) {
294   // CHECK-NEXT: [[C0:%.+]] = "test.constant"() <{value = 1
295   %0 = "test.constant"() {value = 1 : i32} : () -> i32
297   // CHECK-NEXT: return [[C0]]
298   return %0 : i32
301 // CHECK-LABEL: testConstOpUsed
302 func.func @testConstOpUsed() -> (i32) {
303   // CHECK-NEXT: [[C0:%.+]] = "test.constant"() <{value = 1
304   %0 = "test.constant"() {value = 1 : i32} : () -> i32
306   // CHECK-NEXT: [[V0:%.+]] = "test.op_s"([[C0]])
307   %1 = "test.op_s"(%0) {value = 1 : i32} : (i32) -> i32
309   // CHECK-NEXT: return [[V0]]
310   return %1 : i32
313 // CHECK-LABEL: testConstOpReplaced
314 func.func @testConstOpReplaced() -> (i32) {
315   // CHECK-NEXT: [[C0:%.+]] = "test.constant"() <{value = 1
316   %0 = "test.constant"() {value = 1 : i32} : () -> i32
317   %1 = "test.constant"() {value = 2 : i32} : () -> i32
319   // CHECK: [[V0:%.+]] = "test.op_s"([[C0]]) <{value = 2 : i32}
320   %2 = "test.op_r"(%0, %1) : (i32, i32) -> i32
322   // CHECK: [[V0]]
323   return %2 : i32
326 // CHECK-LABEL: testConstOpMatchFailure
327 func.func @testConstOpMatchFailure() -> (i64) {
328   // CHECK-DAG: [[C0:%.+]] = "test.constant"() <{value = 1
329   %0 = "test.constant"() {value = 1 : i64} : () -> i64
331   // CHECK-DAG: [[C1:%.+]] = "test.constant"() <{value = 2
332   %1 = "test.constant"() {value = 2 : i64} : () -> i64
334   // CHECK: [[V0:%.+]] = "test.op_r"([[C0]], [[C1]])
335   %2 = "test.op_r"(%0, %1) : (i64, i64) -> i64
337   // CHECK: [[V0]]
338   return %2 : i64
341 // CHECK-LABEL: testConstOpMatchNonConst
342 func.func @testConstOpMatchNonConst(%arg0 : i32) -> (i32) {
343   // CHECK-DAG: [[C0:%.+]] = "test.constant"() <{value = 1
344   %0 = "test.constant"() {value = 1 : i32} : () -> i32
346   // CHECK: [[V0:%.+]] = "test.op_r"([[C0]], %arg0)
347   %1 = "test.op_r"(%0, %arg0) : (i32, i32) -> i32
349   // CHECK: [[V0]]
350   return %1 : i32
355 //===----------------------------------------------------------------------===//
356 // Test Enum Attributes
357 //===----------------------------------------------------------------------===//
359 // CHECK-LABEL: verifyI32EnumAttr
360 func.func @verifyI32EnumAttr() -> i32 {
361   // CHECK: "test.i32_enum_attr"() <{attr = 10 : i32}
362   %0 = "test.i32_enum_attr"() {attr = 5: i32} : () -> i32
363   return %0 : i32
366 // CHECK-LABEL: verifyI64EnumAttr
367 func.func @verifyI64EnumAttr() -> i32 {
368   // CHECK: "test.i64_enum_attr"() <{attr = 10 : i64}
369   %0 = "test.i64_enum_attr"() {attr = 5: i64} : () -> i32
370   return %0 : i32
373 //===----------------------------------------------------------------------===//
374 // Test ElementsAttr
375 //===----------------------------------------------------------------------===//
377 // CHECK-LABEL: rewrite_i32elementsattr
378 func.func @rewrite_i32elementsattr() -> () {
379   // CHECK: attr = dense<0> : tensor<i32>
380   "test.i32ElementsAttr"() {attr = dense<[3, 5]>:tensor<2xi32>} : () -> ()
381   return
384 // CHECK-LABEL: rewrite_f64elementsattr
385 func.func @rewrite_f64elementsattr() -> () {
386   "test.float_elements_attr"() {
387     // Should match
388     // CHECK: scalar_f32_attr = dense<[5.000000e+00, 6.000000e+00]> : tensor<2xf32>
389     scalar_f32_attr = dense<[3.0, 4.0]> : tensor<2xf32>,
390     tensor_f64_attr = dense<6.0> : tensor<4x8xf64>
391   } : () -> ()
393   "test.float_elements_attr"() {
394     // Should not match
395     // CHECK: scalar_f32_attr = dense<7.000000e+00> : tensor<2xf32>
396     scalar_f32_attr = dense<7.0> : tensor<2xf32>,
397     tensor_f64_attr = dense<3.0> : tensor<4x8xf64>
398   } : () -> ()
399   return
402 //===----------------------------------------------------------------------===//
403 // Test Multi-result Ops
404 //===----------------------------------------------------------------------===//
406 // CHECK-LABEL: @useMultiResultOpToReplaceWhole
407 func.func @useMultiResultOpToReplaceWhole() -> (i32, f32, f32) {
408   // CHECK: %[[A:.*]], %[[B:.*]], %[[C:.*]] = "test.another_three_result"()
409   // CHECK: return %[[A]], %[[B]], %[[C]]
410   %0:3 = "test.three_result"() {kind = 1} : () -> (i32, f32, f32)
411   return %0#0, %0#1, %0#2 : i32, f32, f32
414 // CHECK-LABEL: @useMultiResultOpToReplacePartial1
415 func.func @useMultiResultOpToReplacePartial1() -> (i32, f32, f32) {
416   // CHECK: %[[A:.*]], %[[B:.*]] = "test.two_result"()
417   // CHECK: %[[C:.*]] = "test.one_result1"()
418   // CHECK: return %[[A]], %[[B]], %[[C]]
419   %0:3 = "test.three_result"() {kind = 2} : () -> (i32, f32, f32)
420   return %0#0, %0#1, %0#2 : i32, f32, f32
423 // CHECK-LABEL: @useMultiResultOpToReplacePartial2
424 func.func @useMultiResultOpToReplacePartial2() -> (i32, f32, f32) {
425   // CHECK: %[[A:.*]] = "test.one_result2"()
426   // CHECK: %[[B:.*]], %[[C:.*]] = "test.another_two_result"()
427   // CHECK: return %[[A]], %[[B]], %[[C]]
428   %0:3 = "test.three_result"() {kind = 3} : () -> (i32, f32, f32)
429   return %0#0, %0#1, %0#2 : i32, f32, f32
432 // CHECK-LABEL: @useMultiResultOpResultsSeparately
433 func.func @useMultiResultOpResultsSeparately() -> (i32, f32, f32) {
434   // CHECK: %[[A:.*]], %[[B:.*]] = "test.two_result"()
435   // CHECK: %[[C:.*]] = "test.one_result1"()
436   // CHECK: %[[D:.*]], %[[E:.*]] = "test.two_result"()
437   // CHECK: return %[[A]], %[[C]], %[[E]]
438   %0:3 = "test.three_result"() {kind = 4} : () -> (i32, f32, f32)
439   return %0#0, %0#1, %0#2 : i32, f32, f32
442 // CHECK-LABEL: @constraintOnSourceOpResult
443 func.func @constraintOnSourceOpResult() -> (i32, f32, i32) {
444   // CHECK: %[[A:.*]], %[[B:.*]] = "test.two_result"()
445   // CHECK: %[[C:.*]] = "test.one_result2"()
446   // CHECK: %[[D:.*]] = "test.one_result1"()
447   // CHECK: return %[[A]], %[[B]], %[[C]]
448   %0:2 = "test.two_result"() {kind = 5} : () -> (i32, f32)
449   %1:2 = "test.two_result"() {kind = 5} : () -> (i32, f32)
450   return %0#0, %0#1, %1#0 : i32, f32, i32
453 // CHECK-LABEL: @useAuxiliaryOpToReplaceMultiResultOp
454 func.func @useAuxiliaryOpToReplaceMultiResultOp() -> (i32, f32, f32) {
455   // An auxiliary op is generated to help building the op for replacing the
456   // matched op.
457   // CHECK: %[[A:.*]], %[[B:.*]] = "test.two_result"()
459   // CHECK: %[[C:.*]] = "test.one_result3"(%[[B]])
460   // CHECK: %[[D:.*]], %[[E:.*]] = "test.another_two_result"()
461   // CHECK: return %[[C]], %[[D]], %[[E]]
462   %0:3 = "test.three_result"() {kind = 6} : () -> (i32, f32, f32)
463   return %0#0, %0#1, %0#2 : i32, f32, f32
466 //===----------------------------------------------------------------------===//
467 // Test Multi-result Ops
468 //===----------------------------------------------------------------------===//
470 // CHECK-LABEL: @replaceOneVariadicOutOneVariadicInOp
471 func.func @replaceOneVariadicOutOneVariadicInOp(%arg0: i32, %arg1: i32, %arg2: i32) -> (i32, i32, i32, i32, i32, i32) {
472   // CHECK: %[[cnt1:.*]] = "test.one_variadic_out_one_variadic_in2"(%arg0)
473   // CHECK: %[[cnt2:.*]]:2 = "test.one_variadic_out_one_variadic_in2"(%arg0, %arg1)
474   // CHECK: %[[cnt3:.*]]:3 = "test.one_variadic_out_one_variadic_in2"(%arg0, %arg1, %arg2)
475   // CHECK: return %[[cnt1]], %[[cnt2]]#0, %[[cnt2]]#1, %[[cnt3]]#0, %[[cnt3]]#1, %[[cnt3]]#2
477   %0   = "test.one_variadic_out_one_variadic_in1"(%arg0) : (i32) -> (i32)
478   %1:2 = "test.one_variadic_out_one_variadic_in1"(%arg0, %arg1) : (i32, i32) -> (i32, i32)
479   %2:3 = "test.one_variadic_out_one_variadic_in1"(%arg0, %arg1, %arg2) : (i32, i32, i32) -> (i32, i32, i32)
480   return %0, %1#0, %1#1, %2#0, %2#1, %2#2 : i32, i32, i32, i32, i32, i32
483 // CHECK-LABEL: @replaceMixedVariadicInputOp
484 func.func @replaceMixedVariadicInputOp(%arg0: i32, %arg1: f32, %arg2: i32) -> () {
485   // CHECK: "test.mixed_variadic_in2"(%arg1)
486   // CHECK: "test.mixed_variadic_in2"(%arg0, %arg1, %arg2)
487   // CHECK: "test.mixed_variadic_in2"(%arg0, %arg0, %arg1, %arg2, %arg2)
489   "test.mixed_variadic_in1"(%arg1) : (f32) -> ()
490   "test.mixed_variadic_in1"(%arg0, %arg1, %arg2) : (i32, f32, i32) -> ()
491   "test.mixed_variadic_in1"(%arg0, %arg0, %arg1, %arg2, %arg2) : (i32, i32, f32, i32, i32) -> ()
492   return
495 // CHECK-LABEL: @replaceMixedVariadicOutputOp
496 func.func @replaceMixedVariadicOutputOp() -> (f32, i32, f32, i32, i32, i32, f32, i32, i32) {
497   // CHECK: %[[cnt1:.*]] = "test.mixed_variadic_out2"()
498   // CHECK: %[[cnt3_a:.*]], %[[cnt3_b:.*]], %[[cnt3_c:.*]] = "test.mixed_variadic_out2"()
499   // CHECK: %[[cnt5_a:.*]]:2, %[[cnt5_b:.*]], %[[cnt5_c:.*]]:2 = "test.mixed_variadic_out2"()
500   // CHECK: return %[[cnt1]], %[[cnt3_a]], %[[cnt3_b]], %[[cnt3_c]], %[[cnt5_a]]#0, %[[cnt5_a]]#1, %[[cnt5_b]], %[[cnt5_c]]#0, %[[cnt5_c]]#1
502   %0   = "test.mixed_variadic_out1"() : () -> (f32)
503   %1:3 = "test.mixed_variadic_out1"() : () -> (i32, f32, i32)
504   %2:5 = "test.mixed_variadic_out1"() : () -> (i32, i32, f32, i32, i32)
505   return %0, %1#0, %1#1, %1#2, %2#0, %2#1, %2#2, %2#3, %2#4 : f32, i32, f32, i32, i32, i32, f32, i32, i32
508 // CHECK-LABEL: @generateVariadicOutputOpInNestedPattern
509 func.func @generateVariadicOutputOpInNestedPattern() -> (i32) {
510   // CHECK: %[[cnt5_a:.*]], %[[cnt5_b:.*]]:2, %[[cnt5_c:.*]]:2 = "test.mixed_variadic_out3"()
511   // CHECK: %[[res:.*]] = "test.mixed_variadic_in3"(%[[cnt5_a]], %[[cnt5_b]]#0, %[[cnt5_b]]#1, %[[cnt5_c]]#0, %[[cnt5_c]]#1)
512   // CHECK: return %[[res]]
514   %0 = "test.one_i32_out"() : () -> (i32)
515   return %0 : i32
518 // CHECK-LABEL: @testMatchVariadic
519 func.func @testMatchVariadic(%arg0: i32, %arg1: i32, %arg2: i32, %arg3: i32) -> () {
520   // CHECK: "test.mixed_variadic_in5"(%arg0, %arg1, %arg2) <{attr1 = 0 : i32, pattern_name = "MatchVariadic"}> : (i32, i32, i32) -> ()
521   "test.mixed_variadic_in4"(%arg0, %arg1, %arg2) {attr1 = 0 : i32} : (i32, i32, i32) -> ()
523   // Note: Not rewritten because variadic operand size mismatches.
524   // CHECK: "test.mixed_variadic_in4"(%arg0, %arg1, %arg2, %arg3) <{attr1 = 0 : i32}> : (i32, i32, i32, i32) -> ()
525   "test.mixed_variadic_in4"(%arg0, %arg1, %arg2, %arg3) {attr1 = 0 : i32} : (i32, i32, i32, i32) -> ()
527   return
530 // CHECK-LABEL: @testReplaceVariadic
531 func.func @testReplaceVariadic(%arg0: i32, %arg1: i32, %arg2: i32, %arg3: i32) -> () {
532   // CHECK: "test.mixed_variadic_in3"(%arg2, %arg1, %arg0) <{count = 1 : i32}>
533   "test.mixed_variadic_in5"(%arg0, %arg1, %arg2) <{attr1 = 0 : i32, pattern_name = "MatchInverseVariadic"}> : (i32, i32, i32) -> ()
535   return
538 // CHECK-LABEL: @testMatchVariadicSubDag
539 func.func @testMatchVariadicSubDag(%arg0: i32, %arg1: i32, %arg2: i32) -> () {
540   // CHECK: %[[IN0:.*]] = "test.mixed_variadic_in_out_i32"(%arg0) : (i32) -> i32
541   %0 = "test.mixed_variadic_in_out_i32"(%arg0) : (i32) -> i32
542   // CHECK: %[[IN1:.*]] = "test.mixed_variadic_in_out_i32"(%arg1) : (i32) -> i32
543   %1 = "test.mixed_variadic_in_out_i32"(%arg1) : (i32) -> i32
545   // CHECK: "test.mixed_variadic_in5"(%arg0, %arg1, %arg2) <{attr1 = 1 : i32, pattern_name = "MatchVariadicSubDag"}> : (i32, i32, i32) -> ()
546   "test.mixed_variadic_in4"(%0, %1, %arg2) {attr1 = 1 : i32} : (i32, i32, i32) -> ()
548   // Note: MatchVariadicSubDag doesn't apply
549   // CHECK: "test.mixed_variadic_in4"(%arg0, %arg1, %arg2) <{attr1 = 1 : i32}> : (i32, i32, i32) -> ()
550   "test.mixed_variadic_in4"(%arg0, %arg1, %arg2) {attr1 = 1 : i32} : (i32, i32, i32) -> ()
552   return
555 // CHECK-LABEL: @testMatchVariadicSameSymbol
556 func.func @testMatchVariadicSameSymbol(%arg0: i32, %arg1: i32, %arg2: i32) -> () {
557   // CHECK: "test.mixed_variadic_in5"(%arg0, %arg0, %arg2) <{attr1 = 2 : i32, pattern_name = "MatchVariadicSameSymbol"}> : (i32, i32, i32) -> ()
558   "test.mixed_variadic_in4"(%arg0, %arg0, %arg2) {attr1 = 2 : i32} : (i32, i32, i32) -> ()
560   // Note: MatchVariadicSameSymbol doesn't apply.
561   // CHECK: "test.mixed_variadic_in4"(%arg0, %arg1, %arg2) <{attr1 = 2 : i32}> : (i32, i32, i32) -> ()
562   "test.mixed_variadic_in4"(%arg0, %arg1, %arg2) {attr1 = 2 : i32} : (i32, i32, i32) -> ()
564   return
567 // CHECK-LABEL: @testMatchAndRewriteVariadicFullRange
568 func.func @testMatchAndRewriteVariadicFullRange(%arg0: i32, %arg1: i32, %arg2: i32, %arg3: i32) -> () {
569   // CHECK: "test.mixed_variadic_in6"(%arg2, %arg3, %arg0, %arg1) <{attr1 = -1 : i32}> : (i32, i32, i32, i32) -> ()
570   "test.mixed_variadic_in6"(%arg0, %arg1, %arg2, %arg3) {attr1 = 1 : i32} : (i32, i32, i32, i32) -> ()
572   // Note: MatchAndRewriteVariadicFullRange doesn't apply because the length of each variadic operand is not equal to 2.
573   // CHECK: "test.mixed_variadic_in6"(%arg0, %arg1) <{attr1 = 1 : i32}> : (i32, i32) -> ()
574   "test.mixed_variadic_in6"(%arg0, %arg1) {attr1 = 1 : i32} : (i32, i32) -> ()
576   return
579 // CHECK-LABEL: @testMatchMultiVariadicSubSymbol
580 func.func @testMatchMultiVariadicSubSymbol(%arg0: i32, %arg1: i32, %arg2: i32, %arg3: i32) -> () {
581   // CHECK: "test.mixed_variadic_in5"(%arg2, %arg3, %arg1) <{attr1 = 2 : i32, pattern_name = "MatchMultiVariadicSubSymbol"}> : (i32, i32, i32) -> ()
582   "test.mixed_variadic_in6"(%arg0, %arg1, %arg2, %arg3) {attr1 = 2 : i32} : (i32, i32, i32, i32) -> ()
584   return
587 //===----------------------------------------------------------------------===//
588 // Test that natives calls are only called once during rewrites.
589 //===----------------------------------------------------------------------===//
591 // CHECK-LABEL: redundantTest
592 func.func @redundantTest(%arg0: i32) -> i32 {
593   %0 = "test.op_m"(%arg0) : (i32) -> i32
594   // CHECK: "test.op_m"(%arg0) <{optional_attr = 314159265 : i32}> : (i32) -> i32
595   return %0 : i32
598 //===----------------------------------------------------------------------===//
599 // Test either directive
600 //===----------------------------------------------------------------------===//
602 // CHECK: @either_dag_leaf_only
603 func.func @either_dag_leaf_only_1(%arg0 : i32, %arg1 : i16, %arg2 : i8) -> () {
604   // CHECK: "test.either_op_b"(%arg1, %arg2) : (i16, i8) -> i32
605   %0 = "test.either_op_a"(%arg0, %arg1, %arg2) : (i32, i16, i8) -> i32
606   // CHECK: "test.either_op_b"(%arg1, %arg2) : (i16, i8) -> i32
607   %1 = "test.either_op_a"(%arg1, %arg0, %arg2) : (i16, i32, i8) -> i32
608   return
611 // CHECK: @either_dag_leaf_dag_node
612 func.func @either_dag_leaf_dag_node(%arg0 : i32, %arg1 : i16, %arg2 : i8) -> () {
613   %0 = "test.either_op_b"(%arg0, %arg0) : (i32, i32) -> i32
614   // CHECK: "test.either_op_b"(%arg1, %arg2) : (i16, i8) -> i32
615   %1 = "test.either_op_a"(%0, %arg1, %arg2) : (i32, i16, i8) -> i32
616   // CHECK: "test.either_op_b"(%arg1, %arg2) : (i16, i8) -> i32
617   %2 = "test.either_op_a"(%arg1, %0, %arg2) : (i16, i32, i8) -> i32
618   return
621 // CHECK: @either_dag_node_dag_node
622 func.func @either_dag_node_dag_node(%arg0 : i32, %arg1 : i16, %arg2 : i8) -> () {
623   %0 = "test.either_op_b"(%arg0, %arg0) : (i32, i32) -> i32
624   %1 = "test.either_op_b"(%arg1, %arg1) : (i16, i16) -> i32
625   // CHECK: "test.either_op_b"(%arg1, %arg2) : (i16, i8) -> i32
626   %2 = "test.either_op_a"(%0, %1, %arg2) : (i32, i32, i8) -> i32
627   // CHECK: "test.either_op_b"(%arg1, %arg2) : (i16, i8) -> i32
628   %3 = "test.either_op_a"(%1, %0, %arg2) : (i32, i32, i8) -> i32
629   return
632 //===----------------------------------------------------------------------===//
633 // Test that ops without type deduction can be created with type builders.
634 //===----------------------------------------------------------------------===//
636 func.func @explicitReturnTypeTest(%arg0 : i64) -> i8 {
637   %0 = "test.source_op"(%arg0) {tag = 11 : i32} : (i64) -> i8
638   // CHECK: "test.op_x"(%arg0) : (i64) -> i32
639   // CHECK: "test.op_x"(%0) : (i32) -> i8
640   return %0 : i8
643 func.func @returnTypeBuilderTest(%arg0 : i1) -> i8 {
644   %0 = "test.source_op"(%arg0) {tag = 22 : i32} : (i1) -> i8
645   // CHECK: "test.op_x"(%arg0) : (i1) -> i1
646   // CHECK: "test.op_x"(%0) : (i1) -> i8
647   return %0 : i8
650 func.func @multipleReturnTypeBuildTest(%arg0 : i1) -> i1 {
651   %0 = "test.source_op"(%arg0) {tag = 33 : i32} : (i1) -> i1
652   // CHECK: "test.one_to_two"(%arg0) : (i1) -> (i64, i32)
653   // CHECK: "test.op_x"(%0#0) : (i64) -> i32
654   // CHECK: "test.op_x"(%0#1) : (i32) -> i64
655   // CHECK: "test.two_to_one"(%1, %2) : (i32, i64) -> i1
656   return %0 : i1
659 func.func @copyValueType(%arg0 : i8) -> i32 {
660   %0 = "test.source_op"(%arg0) {tag = 44 : i32} : (i8) -> i32
661   // CHECK: "test.op_x"(%arg0) : (i8) -> i8
662   // CHECK: "test.op_x"(%0) : (i8) -> i32
663   return %0 : i32
666 func.func @multipleReturnTypeDifferent(%arg0 : i1) -> i64 {
667   %0 = "test.source_op"(%arg0) {tag = 55 : i32} : (i1) -> i64
668   // CHECK: "test.one_to_two"(%arg0) : (i1) -> (i1, i64)
669   // CHECK: "test.two_to_one"(%0#0, %0#1) : (i1, i64) -> i64
670   return %0 : i64
673 //===----------------------------------------------------------------------===//
674 // Test that multiple trailing directives can be mixed in patterns.
675 //===----------------------------------------------------------------------===//
677 func.func @returnTypeAndLocation(%arg0 : i32) -> i1 {
678   %0 = "test.source_op"(%arg0) {tag = 66 : i32} : (i32) -> i1
679   // CHECK: "test.op_x"(%arg0) : (i32) -> i32 loc("loc1")
680   // CHECK: "test.op_x"(%arg0) : (i32) -> i32 loc("loc2")
681   // CHECK: "test.two_to_one"(%0, %1) : (i32, i32) -> i1
682   return %0 : i1
685 //===----------------------------------------------------------------------===//
686 // Test that patterns can create ConstantStrAttr
687 //===----------------------------------------------------------------------===//
689 func.func @testConstantStrAttr() -> () {
690   // CHECK: test.has_str_value {value = "foo"}
691   test.no_str_value {value = "bar"}
692   return
695 //===----------------------------------------------------------------------===//
696 // Test that patterns with variadics propagate sizes
697 //===----------------------------------------------------------------------===//
699 func.func @testVariadic(%arg_0: i32, %arg_1: i32, %brg: i64,
700     %crg_0: f32, %crg_1: f32, %crg_2: f32, %crg_3: f32) -> () {
701   // CHECK: "test.variadic_rewrite_dst_op"(%arg2, %arg3, %arg4, %arg5, %arg6, %arg0, %arg1) <{operandSegmentSizes = array<i32: 1, 4, 2>}> : (i64, f32, f32, f32, f32, i32, i32) -> ()
702   "test.variadic_rewrite_src_op"(%arg_0, %arg_1, %brg,
703     %crg_0, %crg_1, %crg_2, %crg_3) {operandSegmentSizes = array<i32: 2, 1, 4>} :
704     (i32, i32, i64, f32, f32, f32, f32) -> ()
705   return