[TableGen] Split DAGISelMatcherOpt FactorNodes into 2 functions. NFC (#125330)
[llvm-project.git] / mlir / test / Conversion / OneToNTypeConversion / one-to-n-type-conversion.mlir
blob611ec0265cd37b7237b63af7eeeba02bea08a970
1 // RUN: mlir-opt %s -split-input-file \
2 // RUN:   -test-one-to-n-type-conversion="convert-tuple-ops" \
3 // RUN: | FileCheck --check-prefix=CHECK-TUP %s
5 // RUN: mlir-opt %s -split-input-file \
6 // RUN:   -test-one-to-n-type-conversion="convert-func-ops" \
7 // RUN: | FileCheck --check-prefix=CHECK-FUNC %s
9 // RUN: mlir-opt %s -split-input-file \
10 // RUN:   -test-one-to-n-type-conversion="convert-func-ops convert-tuple-ops" \
11 // RUN: | FileCheck --check-prefix=CHECK-BOTH %s
13 // Test case: Matching nested packs and unpacks just disappear.
15 // CHECK-TUP-LABEL: func.func @pack_unpack(
16 // CHECK-TUP-SAME:                          %[[ARG0:.*]]: i1,
17 // CHECK-TUP-SAME:                          %[[ARG1:.*]]: i2) -> (i1, i2) {
18 // CHECK-TUP-DAG:     return %[[ARG0]], %[[ARG1]] : i1, i2
19 func.func @pack_unpack(%arg0: i1, %arg1: i2) -> (i1, i2) {
20   %0 = "test.make_tuple"() : () -> tuple<>
21   %1 = "test.make_tuple"(%arg1) : (i2) -> tuple<i2>
22   %2 = "test.make_tuple"(%1) : (tuple<i2>) -> tuple<tuple<i2>>
23   %3 = "test.make_tuple"(%0, %arg0, %2) : (tuple<>, i1, tuple<tuple<i2>>) -> tuple<tuple<>, i1, tuple<tuple<i2>>>
24   %4 = "test.get_tuple_element"(%3) {index = 0 : i32} : (tuple<tuple<>, i1, tuple<tuple<i2>>>) -> tuple<>
25   %5 = "test.get_tuple_element"(%3) {index = 1 : i32} : (tuple<tuple<>, i1, tuple<tuple<i2>>>) -> i1
26   %6 = "test.get_tuple_element"(%3) {index = 2 : i32} : (tuple<tuple<>, i1, tuple<tuple<i2>>>) -> tuple<tuple<i2>>
27   %7 = "test.get_tuple_element"(%6) {index = 0 : i32} : (tuple<tuple<i2>>) -> tuple<i2>
28   %8 = "test.get_tuple_element"(%7) {index = 0 : i32} : (tuple<i2>) -> i2
29   return %5, %8 : i1, i2
32 // -----
34 // Test case: Appropriate materializations are created depending on which ops
35 // are converted.
37 // If we only convert the tuple ops, the original `get_tuple_element` ops will
38 // disappear but one target materialization will be inserted from the
39 // unconverted function arguments to each of the return values (which have
40 // redundancy among themselves).
42 // CHECK-TUP-LABEL: func.func @materializations_tuple_args(
43 // CHECK-TUP-SAME:                                         %[[ARG0:.*]]: tuple<tuple<>, i1, tuple<tuple<i2>>>) -> (i1, i2) {
44 // CHECK-TUP-DAG:     %[[V0:.*]] = "test.get_tuple_element"(%[[ARG0]]) <{index = 0 : i32}> : (tuple<tuple<>, i1, tuple<tuple<i2>>>) -> tuple<>
45 // CHECK-TUP-DAG:     %[[V1:.*]] = "test.get_tuple_element"(%[[ARG0]]) <{index = 1 : i32}> : (tuple<tuple<>, i1, tuple<tuple<i2>>>) -> i1
46 // CHECK-TUP-DAG:     %[[V2:.*]] = "test.get_tuple_element"(%[[ARG0]]) <{index = 2 : i32}> : (tuple<tuple<>, i1, tuple<tuple<i2>>>) -> tuple<tuple<i2>>
47 // CHECK-TUP-DAG:     %[[V3:.*]] = "test.get_tuple_element"(%[[V2]]) <{index = 0 : i32}> : (tuple<tuple<i2>>) -> tuple<i2>
48 // CHECK-TUP-DAG:     %[[V4:.*]] = "test.get_tuple_element"(%[[V3]]) <{index = 0 : i32}> : (tuple<i2>) -> i2
49 // CHECK-TUP-DAG:     %[[V5:.*]] = "test.get_tuple_element"(%[[ARG0]]) <{index = 0 : i32}> : (tuple<tuple<>, i1, tuple<tuple<i2>>>) -> tuple<>
50 // CHECK-TUP-DAG:     %[[V6:.*]] = "test.get_tuple_element"(%[[ARG0]]) <{index = 1 : i32}> : (tuple<tuple<>, i1, tuple<tuple<i2>>>) -> i1
51 // CHECK-TUP-DAG:     %[[V7:.*]] = "test.get_tuple_element"(%[[ARG0]]) <{index = 2 : i32}> : (tuple<tuple<>, i1, tuple<tuple<i2>>>) -> tuple<tuple<i2>>
52 // CHECK-TUP-DAG:     %[[V8:.*]] = "test.get_tuple_element"(%[[V7]]) <{index = 0 : i32}> : (tuple<tuple<i2>>) -> tuple<i2>
53 // CHECK-TUP-DAG:     %[[V9:.*]] = "test.get_tuple_element"(%[[V8]]) <{index = 0 : i32}> : (tuple<i2>) -> i2
54 // CHECK-TUP-DAG:     return %[[V1]], %[[V9]] : i1, i2
56 // If we only convert the func ops, argument materializations are created from
57 // the converted tuple elements back to the tuples that the `get_tuple_element`
58 // ops expect.
60 // CHECK-FUNC-LABEL: func.func @materializations_tuple_args(
61 // CHECK-FUNC-SAME:                                         %[[ARG0:.*]]: i1,
62 // CHECK-FUNC-SAME:                                         %[[ARG1:.*]]: i2) -> (i1, i2) {
63 // CHECK-FUNC-DAG:     %[[V0:.*]] = "test.make_tuple"() : () -> tuple<>
64 // CHECK-FUNC-DAG:     %[[V1:.*]] = "test.make_tuple"(%[[ARG1]]) : (i2) -> tuple<i2>
65 // CHECK-FUNC-DAG:     %[[V2:.*]] = "test.make_tuple"(%[[V1]]) : (tuple<i2>) -> tuple<tuple<i2>>
66 // CHECK-FUNC-DAG:     %[[V3:.*]] = "test.make_tuple"(%[[V0]], %[[ARG0]], %[[V2]]) : (tuple<>, i1, tuple<tuple<i2>>) -> tuple<tuple<>, i1, tuple<tuple<i2>>>
67 // CHECK-FUNC-DAG:     %[[V4:.*]] = "test.get_tuple_element"(%[[V3]]) <{index = 0 : i32}> : (tuple<tuple<>, i1, tuple<tuple<i2>>>) -> tuple<>
68 // CHECK-FUNC-DAG:     %[[V5:.*]] = "test.get_tuple_element"(%[[V3]]) <{index = 1 : i32}> : (tuple<tuple<>, i1, tuple<tuple<i2>>>) -> i1
69 // CHECK-FUNC-DAG:     %[[V6:.*]] = "test.get_tuple_element"(%[[V3]]) <{index = 2 : i32}> : (tuple<tuple<>, i1, tuple<tuple<i2>>>) -> tuple<tuple<i2>>
70 // CHECK-FUNC-DAG:     %[[V7:.*]] = "test.get_tuple_element"(%[[V6]]) <{index = 0 : i32}> : (tuple<tuple<i2>>) -> tuple<i2>
71 // CHECK-FUNC-DAG:     %[[V8:.*]] = "test.get_tuple_element"(%[[V7]]) <{index = 0 : i32}> : (tuple<i2>) -> i2
72 // CHECK-FUNC-DAG:     return %[[V5]], %[[V8]] : i1, i2
74 // If we convert both tuple and func ops, basically everything disappears.
76 // CHECK-BOTH-LABEL: func.func @materializations_tuple_args(
77 // CHECK-BOTH-SAME:                                         %[[ARG0:.*]]: i1,
78 // CHECK-BOTH-SAME:                                         %[[ARG1:.*]]: i2) -> (i1, i2) {
79 // CHECK-BOTH-DAG:     return %[[ARG0]], %[[ARG1]] : i1, i2
81 func.func @materializations_tuple_args(%arg0: tuple<tuple<>, i1, tuple<tuple<i2>>>) -> (i1, i2) {
82   %0 = "test.get_tuple_element"(%arg0) {index = 0 : i32} : (tuple<tuple<>, i1, tuple<tuple<i2>>>) -> tuple<>
83   %1 = "test.get_tuple_element"(%arg0) {index = 1 : i32} : (tuple<tuple<>, i1, tuple<tuple<i2>>>) -> i1
84   %2 = "test.get_tuple_element"(%arg0) {index = 2 : i32} : (tuple<tuple<>, i1, tuple<tuple<i2>>>) -> tuple<tuple<i2>>
85   %3 = "test.get_tuple_element"(%2) {index = 0 : i32} : (tuple<tuple<i2>>) -> tuple<i2>
86   %4 = "test.get_tuple_element"(%3) {index = 0 : i32} : (tuple<i2>) -> i2
87   return %1, %4 : i1, i2
89 // -----
91 // Test case: Appropriate materializations are created depending on which ops
92 // are converted.
94 // If we only convert the tuple ops, the original `make_tuple` ops will
95 // disappear but a source materialization will be inserted from the result of
96 // conversion (which, for `make_tuple`, are the original ops that get forwarded)
97 // to the operands of the unconverted op with the original type (i.e.,
98 // `return`).
100 // CHECK-TUP-LABEL: func.func @materializations_tuple_return(
101 // CHECK-TUP-SAME:                                           %[[ARG0:.*]]: i1,
102 // CHECK-TUP-SAME:                                           %[[ARG1:.*]]: i2) -> tuple<tuple<>, i1, tuple<tuple<i2>>> {
103 // CHECK-TUP-DAG:     %[[V0:.*]] = "test.make_tuple"() : () -> tuple<>
104 // CHECK-TUP-DAG:     %[[V1:.*]] = "test.make_tuple"(%[[ARG1]]) : (i2) -> tuple<i2>
105 // CHECK-TUP-DAG:     %[[V2:.*]] = "test.make_tuple"(%[[V1]]) : (tuple<i2>) -> tuple<tuple<i2>>
106 // CHECK-TUP-DAG:     %[[V3:.*]] = "test.make_tuple"(%[[V0]], %[[ARG0]], %[[V2]]) : (tuple<>, i1, tuple<tuple<i2>>) -> tuple<tuple<>, i1, tuple<tuple<i2>>>
107 // CHECK-TUP-DAG:     return %[[V3]] : tuple<tuple<>, i1, tuple<tuple<i2>>>
109 // If we only convert the func ops, target materializations are created from
110 // original tuples produced by `make_tuple` to its constituent elements that the
111 // converted op (i.e., `return`) expect.
113 // CHECK-FUNC-LABEL: func.func @materializations_tuple_return(
114 // CHECK-FUNC-SAME:                                           %[[ARG0:.*]]: i1,
115 // CHECK-FUNC-SAME:                                           %[[ARG1:.*]]: i2) -> (i1, i2) {
116 // CHECK-FUNC-DAG:     %[[V0:.*]] = "test.make_tuple"() : () -> tuple<>
117 // CHECK-FUNC-DAG:     %[[V1:.*]] = "test.make_tuple"(%[[ARG1]]) : (i2) -> tuple<i2>
118 // CHECK-FUNC-DAG:     %[[V2:.*]] = "test.make_tuple"(%[[V1]]) : (tuple<i2>) -> tuple<tuple<i2>>
119 // CHECK-FUNC-DAG:     %[[V3:.*]] = "test.make_tuple"(%[[V0]], %[[ARG0]], %[[V2]]) : (tuple<>, i1, tuple<tuple<i2>>) -> tuple<tuple<>, i1, tuple<tuple<i2>>>
120 // CHECK-FUNC-DAG:     %[[V4:.*]] = "test.get_tuple_element"(%[[V3]]) <{index = 0 : i32}> : (tuple<tuple<>, i1, tuple<tuple<i2>>>) -> tuple<>
121 // CHECK-FUNC-DAG:     %[[V5:.*]] = "test.get_tuple_element"(%[[V3]]) <{index = 1 : i32}> : (tuple<tuple<>, i1, tuple<tuple<i2>>>) -> i1
122 // CHECK-FUNC-DAG:     %[[V6:.*]] = "test.get_tuple_element"(%[[V3]]) <{index = 2 : i32}> : (tuple<tuple<>, i1, tuple<tuple<i2>>>) -> tuple<tuple<i2>>
123 // CHECK-FUNC-DAG:     %[[V7:.*]] = "test.get_tuple_element"(%[[V6]]) <{index = 0 : i32}> : (tuple<tuple<i2>>) -> tuple<i2>
124 // CHECK-FUNC-DAG:     %[[V8:.*]] = "test.get_tuple_element"(%[[V7]]) <{index = 0 : i32}> : (tuple<i2>) -> i2
125 // CHECK-FUNC-DAG:     return %[[V5]], %[[V8]] : i1, i2
127 // If we convert both tuple and func ops, basically everything disappears.
129 // CHECK-BOTH-LABEL: func.func @materializations_tuple_return(
130 // CHECK-BOTH-SAME:                                           %[[ARG0:.*]]: i1,
131 // CHECK-BOTH-SAME:                                           %[[ARG1:.*]]: i2) -> (i1, i2) {
132 // CHECK-BOTH-DAG:     return %[[ARG0]], %[[ARG1]] : i1, i2
134 func.func @materializations_tuple_return(%arg0: i1, %arg1: i2) -> tuple<tuple<>, i1, tuple<tuple<i2>>> {
135   %0 = "test.make_tuple"() : () -> tuple<>
136   %1 = "test.make_tuple"(%arg1) : (i2) -> tuple<i2>
137   %2 = "test.make_tuple"(%1) : (tuple<i2>) -> tuple<tuple<i2>>
138   %3 = "test.make_tuple"(%0, %arg0, %2) : (tuple<>, i1, tuple<tuple<i2>>) -> tuple<tuple<>, i1, tuple<tuple<i2>>>
139   return %3 : tuple<tuple<>, i1, tuple<tuple<i2>>>