[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / TableGen / GICombinerEmitter / parse-match-pattern.td
blob771100171fe9043791e0ceaa2bb8fc46a8b8c6e3
1 // RUN: llvm-tblgen -I %p/../../../include -gen-global-isel-combiner \
2 // RUN:     -combiners=MyCombiner -gicombiner-stop-after-parse %s \
3 // RUN:     -o /dev/null -debug 2>&1 | FileCheck %s
4 // REQUIRES: asserts
6 include "llvm/Target/Target.td"
7 include "llvm/Target/GlobalISel/Combine.td"
9 def MyTargetISA : InstrInfo;
10 def MyTarget : Target { let InstructionSet = MyTargetISA; }
12 def dummy;
14 def R0 : Register<"r0"> { let Namespace = "MyTarget"; }
15 def GPR32 : RegisterClass<"MyTarget", [i32], 32, (add R0)>;
16 class I<dag OOps, dag IOps, list<dag> Pat>
17   : Instruction {
18   let Namespace = "MyTarget";
19   let OutOperandList = OOps;
20   let InOperandList = IOps;
21   let Pattern = Pat;
23 def MOV : I<(outs GPR32:$dst), (ins GPR32:$src1), []>;
24 def MOV2 : I<(outs GPR32:$dst), (ins GPR32:$src1), []>;
26 def trivial : GICombineRule<
27   (defs root:$d),
28   (match (MOV $d, $s)),
29   (apply [{ APPLY }])>;
31 // CHECK-LABEL: Parsed rule defs/match for 'trivial'
33 // The matchdag block is a fairly direct dump of the information that was read.
34 // It's oriented towards the data structures within tablegen.
35 // CHECK-NEXT: matchdag {
36 // CHECK-NEXT:     (MOV 0:dst<def>, 1:src1):$__anon0_0 // $d=getOperand(0), $s=getOperand(1)
37 // CHECK-NEXT:     <<$mi.getOpcode() == MOV>>:$__anonpred0_1
38 // CHECK-NEXT:     __anon0_0 ==> __anonpred0_1[mi]
39 // CHECK-NEXT: {{^}$}}
41 // The digraph block is a human-oriented dump of the information that was read.
42 // Run it through graphviz to produce a nice DAG showing the matcher behaviour.
43 // CHECK-NEXT: digraph "trivial" {
44 // CHECK-NEXT:   rankdir="BT"
45 // CHECK-NEXT:   Node[[N1:(0x)?[0-9a-fA-F]+]] [shape=record,label="{{[{]{}}<s0>#0 $dst|<s1>#1 $src1}|__anon0_0|MOV|Match starts here|$d=getOperand(0), $s=getOperand(1)|{{(0x)?[0-9a-fA-F]+}}|{<d0>#0 $dst|<d1>#1 $src1}}",color=red]
46 // CHECK-NEXT:   Pred[[P1:(0x)?[0-9a-fA-F]+]] [shape=record,label="{{[{]{}}<s0>#0 $$|<s1>#1 $mi}|__anonpred0_1|$mi.getOpcode() == MOV|{{(0x)?[0-9a-fA-F]+}}|{<d0>#0 $$|<d1>#1 $mi}}",style=dotted]
47 // CHECK-NEXT:   Node[[N1]]:e -> Pred[[P1]]:d1:s [style=dotted]
48 // CHECK-NEXT: {{^}$}}
50 def simple : GICombineRule<
51   (defs root:$d),
52   (match (MOV $t, $s),
53          (MOV $d, $t)),
54   (apply [{ APPLY }])>;
56 // CHECK-LABEL: Parsed rule defs/match for 'simple'
58 // CHECK-NEXT: matchdag {
59 // CHECK-NEXT:     (MOV 0:dst<def>, 1:src1):$__anon1_0 // $t=getOperand(0), $s=getOperand(1)
60 // CHECK-NEXT:     (MOV 0:dst<def>, 1:src1):$__anon1_2 // $d=getOperand(0), $t=getOperand(1)
61 // CHECK-NEXT:     __anon1_2[src1] --[t]--> __anon1_0[dst]
62 // CHECK-NEXT:     <<$mi.getOpcode() == MOV>>:$__anonpred1_1
63 // CHECK-NEXT:     <<$mi.getOpcode() == MOV>>:$__anonpred1_3
64 // CHECK-NEXT:     __anon1_0 ==> __anonpred1_1[mi]
65 // CHECK-NEXT:     __anon1_2 ==> __anonpred1_3[mi]
66 // CHECK-NEXT: {{^}$}}
68 // CHECK-NEXT: digraph "simple" {
69 // CHECK-NEXT:   rankdir="BT"
70 // CHECK-NEXT:   Node[[N1:(0x)?[0-9a-fA-F]+]] [shape=record,label="{{[{]{}}<s0>#0 $dst|<s1>#1 $src1}|__anon1_0|MOV|$t=getOperand(0), $s=getOperand(1)|{{(0x)?[0-9a-fA-F]+}}|{<d0>#0 $dst|<d1>#1 $src1}}"]
71 // CHECK-NEXT:   Node[[N2:(0x)?[0-9a-fA-F]+]] [shape=record,label="{{[{]{}}<s0>#0 $dst|<s1>#1 $src1}|__anon1_2|MOV|Match starts here|$d=getOperand(0), $t=getOperand(1)|{{(0x)?[0-9a-fA-F]+}}|{<d0>#0 $dst|<d1>#1 $src1}}",color=red]
72 // CHECK-NEXT:   Node[[N2]]:s1:n -> Node[[N1]]:d0:s [label="$t"]
73 // CHECK-NEXT:   Pred[[P1:(0x)?[0-9a-fA-F]+]] [shape=record,label="{{[{]{}}<s0>#0 $$|<s1>#1 $mi}|__anonpred1_1|$mi.getOpcode() == MOV|{{(0x)?[0-9a-fA-F]+}}|{<d0>#0 $$|<d1>#1 $mi}}",style=dotted]
74 // CHECK-NEXT:   Pred[[P2:(0x)?[0-9a-fA-F]+]] [shape=record,label="{{[{]{}}<s0>#0 $$|<s1>#1 $mi}|__anonpred1_3|$mi.getOpcode() == MOV|{{(0x)?[0-9a-fA-F]+}}|{<d0>#0 $$|<d1>#1 $mi}}",style=dotted]
75 // CHECK-NEXT:   Node[[N1]]:e -> Pred[[P1]]:d1:s [style=dotted]
76 // CHECK-NEXT:   Node[[N2]]:e -> Pred[[P2]]:d1:s [style=dotted]
77 // CHECK-NEXT: {{^}$}}
79 def multiroot : GICombineRule<
80   (defs root:$d1, root:$d2),
81   (match (MOV $s, $s2),
82          (MOV $d1, $s),
83          (MOV $d2, $s)),
84   (apply [{ APPLY }])>;
86 // CHECK-LABEL: Parsed rule defs/match for 'multiroot'
88 // CHECK-NEXT: matchdag {
89 // CHECK-NEXT:     (MOV 0:dst<def>, 1:src1):$__anon2_0 // $s=getOperand(0), $s2=getOperand(1)
90 // CHECK-NEXT:     (MOV 0:dst<def>, 1:src1):$__anon2_2 // $d1=getOperand(0), $s=getOperand(1)
91 // CHECK-NEXT:     (MOV 0:dst<def>, 1:src1):$__anon2_4 // $d2=getOperand(0), $s=getOperand(1)
92 // CHECK-NEXT:     __anon2_2[src1] --[s]--> __anon2_0[dst]
93 // CHECK-NEXT:     __anon2_4[src1] --[s]--> __anon2_0[dst]
94 // CHECK-NEXT:     <<$mi.getOpcode() == MOV>>:$__anonpred2_1
95 // CHECK-NEXT:     <<$mi.getOpcode() == MOV>>:$__anonpred2_3
96 // CHECK-NEXT:     <<$mi.getOpcode() == MOV>>:$__anonpred2_5
97 // CHECK-NEXT:     <<$mi0 == $mi1>>:$__anonpred2_6
98 // CHECK-NEXT:     __anon2_0 ==> __anonpred2_1[mi]
99 // CHECK-NEXT:     __anon2_2 ==> __anonpred2_3[mi]
100 // CHECK-NEXT:     __anon2_4 ==> __anonpred2_5[mi]
101 // CHECK-NEXT:     __anon2_2[src1] ==> __anonpred2_6[mi0]
102 // CHECK-NEXT:     __anon2_4[src1] ==> __anonpred2_6[mi1]
103 // CHECK-NEXT: {{^}$}}
105 // CHECK-NEXT: digraph "multiroot" {
106 // CHECK-NEXT:   rankdir="BT"
107 // CHECK-NEXT:   Node[[N1:(0x)?[0-9a-fA-F]+]] [shape=record,label="{{[{]{}}<s0>#0 $dst|<s1>#1 $src1}|__anon2_0|MOV|$s=getOperand(0), $s2=getOperand(1)|{{(0x)?[0-9a-fA-F]+}}|{<d0>#0 $dst|<d1>#1 $src1}}"]
108 // CHECK-NEXT:   Node[[N2:(0x)?[0-9a-fA-F]+]] [shape=record,label="{{[{]{}}<s0>#0 $dst|<s1>#1 $src1}|__anon2_2|MOV|Match starts here|$d1=getOperand(0), $s=getOperand(1)|{{(0x)?[0-9a-fA-F]+}}|{<d0>#0 $dst|<d1>#1 $src1}}",color=red]
109 // CHECK-NEXT:   Node[[N3:(0x)?[0-9a-fA-F]+]] [shape=record,label="{{[{]{}}<s0>#0 $dst|<s1>#1 $src1}|__anon2_4|MOV|Match starts here|$d2=getOperand(0), $s=getOperand(1)|{{(0x)?[0-9a-fA-F]+}}|{<d0>#0 $dst|<d1>#1 $src1}}",color=red]
110 // CHECK-NEXT:   Node[[N2]]:s1:n -> Node[[N1]]:d0:s [label="$s"]
111 // CHECK-NEXT:   Node[[N3]]:s1:n -> Node[[N1]]:d0:s [label="$s"]
112 // CHECK-NEXT:   Pred[[P1:(0x)?[0-9a-fA-F]+]] [shape=record,label="{{[{]{}}<s0>#0 $$|<s1>#1 $mi}|__anonpred2_1|$mi.getOpcode() == MOV|{{(0x)?[0-9a-fA-F]+}}|{<d0>#0 $$|<d1>#1 $mi}}",style=dotted]
113 // CHECK-NEXT:   Pred[[P2:(0x)?[0-9a-fA-F]+]] [shape=record,label="{{[{]{}}<s0>#0 $$|<s1>#1 $mi}|__anonpred2_3|$mi.getOpcode() == MOV|{{(0x)?[0-9a-fA-F]+}}|{<d0>#0 $$|<d1>#1 $mi}}",style=dotted]
114 // CHECK-NEXT:   Pred[[P3:(0x)?[0-9a-fA-F]+]] [shape=record,label="{{[{]{}}<s0>#0 $$|<s1>#1 $mi}|__anonpred2_5|$mi.getOpcode() == MOV|{{(0x)?[0-9a-fA-F]+}}|{<d0>#0 $$|<d1>#1 $mi}}",style=dotted]
115 // CHECK-NEXT:   Pred[[P4:(0x)?[0-9a-fA-F]+]] [shape=record,label="{{[{]{}}<s0>#0 $$|<s1>#1 $mi0|<s2>#2 $mi1}|__anonpred2_6|$mi0 == $mi1|{{(0x)?[0-9a-fA-F]+}}|{<d0>#0 $$|<d1>#1 $mi0|<d2>#2 $mi1}}",style=dotted]
116 // CHECK-NEXT:   Node[[N1]]:e -> Pred[[P1]]:d1:s [style=dotted]
117 // CHECK-NEXT:   Node[[N2]]:e -> Pred[[P2]]:d1:s [style=dotted]
118 // CHECK-NEXT:   Node[[N3]]:e -> Pred[[P3]]:d1:s [style=dotted]
119 // CHECK-NEXT:   Node[[N2]]:s1:n -> Pred[[P4]]:d1:s [style=dotted]
120 // CHECK-NEXT:   Node[[N3]]:s1:n -> Pred[[P4]]:d2:s [style=dotted]
121 // CHECK-NEXT: {{^}$}}
123 def nonstandardroot : GICombineRule<
124   (defs root:$s),
125   (match (MOV $s, $s2),
126          (MOV $d1, $s),
127          (MOV $d2, $s)),
128   (apply [{ APPLY }])>;
130 // CHECK-LABEL: Parsed rule defs/match for 'nonstandardroot'
132 // CHECK-NEXT: matchdag {
133 // CHECK-NEXT:     (MOV 0:dst<def>, 1:src1):$__anon3_0 // $s=getOperand(0), $s2=getOperand(1)
134 // CHECK-NEXT:     (MOV 0:dst<def>, 1:src1):$__anon3_2 // $d1=getOperand(0), $s=getOperand(1)
135 // CHECK-NEXT:     (MOV 0:dst<def>, 1:src1):$__anon3_4 // $d2=getOperand(0), $s=getOperand(1)
136 // CHECK-NEXT:     __anon3_0[dst] --[s]--> __anon3_2[src1]
137 // CHECK-NEXT:     __anon3_0[dst] --[s]--> __anon3_4[src1]
138 // CHECK-NEXT:     <<$mi.getOpcode() == MOV>>:$__anonpred3_1
139 // CHECK-NEXT:     <<$mi.getOpcode() == MOV>>:$__anonpred3_3
140 // CHECK-NEXT:     <<$mi.getOpcode() == MOV>>:$__anonpred3_5
141 // CHECK-NEXT:     <<$mi0 == $mi1>>:$__anonpred3_6
142 // CHECK-NEXT:     __anon3_0 ==> __anonpred3_1[mi]
143 // CHECK-NEXT:     __anon3_2 ==> __anonpred3_3[mi]
144 // CHECK-NEXT:     __anon3_4 ==> __anonpred3_5[mi]
145 // CHECK-NEXT:     __anon3_2[src1] ==> __anonpred3_6[mi0]
146 // CHECK-NEXT:     __anon3_4[src1] ==> __anonpred3_6[mi1]
147 // CHECK-NEXT: {{^}$}}
149 // CHECK-NEXT: digraph "nonstandardroot" {
150 // CHECK-NEXT:   rankdir="BT"
151 // CHECK-NEXT:   Node[[N1:(0x)?[0-9a-fA-F]+]] [shape=record,label="{{[{]{}}<s0>#0 $dst|<s1>#1 $src1}|__anon3_0|MOV|Match starts here|$s=getOperand(0), $s2=getOperand(1)|{{(0x)?[0-9a-fA-F]+}}|{<d0>#0 $dst|<d1>#1 $src1}}",color=red]
152 // CHECK-NEXT:   Node[[N2:(0x)?[0-9a-fA-F]+]] [shape=record,label="{{[{]{}}<s0>#0 $dst|<s1>#1 $src1}|__anon3_2|MOV|$d1=getOperand(0), $s=getOperand(1)|{{(0x)?[0-9a-fA-F]+}}|{<d0>#0 $dst|<d1>#1 $src1}}"]
153 // CHECK-NEXT:   Node[[N3:(0x)?[0-9a-fA-F]+]] [shape=record,label="{{[{]{}}<s0>#0 $dst|<s1>#1 $src1}|__anon3_4|MOV|$d2=getOperand(0), $s=getOperand(1)|{{(0x)?[0-9a-fA-F]+}}|{<d0>#0 $dst|<d1>#1 $src1}}"]
154 // CHECK-NEXT:   Node[[N2]]:s1:n -> Node[[N1]]:d0:s [label="$s",dir=back,arrowtail=crow]
155 // CHECK-NEXT:   Node[[N3]]:s1:n -> Node[[N1]]:d0:s [label="$s",dir=back,arrowtail=crow]
156 // CHECK-NEXT:   Pred[[P1:(0x)?[0-9a-fA-F]+]] [shape=record,label="{{[{]{}}<s0>#0 $$|<s1>#1 $mi}|__anonpred3_1|$mi.getOpcode() == MOV|{{(0x)?[0-9a-fA-F]+}}|{<d0>#0 $$|<d1>#1 $mi}}",style=dotted]
157 // CHECK-NEXT:   Pred[[P2:(0x)?[0-9a-fA-F]+]] [shape=record,label="{{[{]{}}<s0>#0 $$|<s1>#1 $mi}|__anonpred3_3|$mi.getOpcode() == MOV|{{(0x)?[0-9a-fA-F]+}}|{<d0>#0 $$|<d1>#1 $mi}}",style=dotted]
158 // CHECK-NEXT:   Pred[[P3:(0x)?[0-9a-fA-F]+]] [shape=record,label="{{[{]{}}<s0>#0 $$|<s1>#1 $mi}|__anonpred3_5|$mi.getOpcode() == MOV|{{(0x)?[0-9a-fA-F]+}}|{<d0>#0 $$|<d1>#1 $mi}}",style=dotted]
159 // CHECK-NEXT:   Pred[[P4:(0x)?[0-9a-fA-F]+]] [shape=record,label="{{[{]{}}<s0>#0 $$|<s1>#1 $mi0|<s2>#2 $mi1}|__anonpred3_6|$mi0 == $mi1|{{(0x)?[0-9a-fA-F]+}}|{<d0>#0 $$|<d1>#1 $mi0|<d2>#2 $mi1}}",style=dotted]
160 // CHECK-NEXT:   Node[[N1]]:e -> Pred[[P1]]:d1:s [style=dotted]
161 // CHECK-NEXT:   Node[[N2]]:e -> Pred[[P2]]:d1:s [style=dotted]
162 // CHECK-NEXT:   Node[[N3]]:e -> Pred[[P3]]:d1:s [style=dotted]
163 // CHECK-NEXT:   Node[[N2]]:s1:n -> Pred[[P4]]:d1:s [style=dotted]
164 // CHECK-NEXT:   Node[[N3]]:s1:n -> Pred[[P4]]:d2:s [style=dotted]
165 // CHECK-NEXT: {{^}$}}
167 def multiref_use : GICombineRule<
168   (defs root:$d1, root:$d2),
169   (match (MOV $d1, $s),
170          (MOV $d2, $s)),
171   (apply [{ APPLY }])>;
173 // CHECK-LABEL: Parsed rule defs/match for 'multiref_use'
175 // CHECK-NEXT: matchdag {
176 // CHECK-NEXT:     (MOV 0:dst<def>, 1:src1):$__anon4_0 // $d1=getOperand(0), $s=getOperand(1)
177 // CHECK-NEXT:     (MOV 0:dst<def>, 1:src1):$__anon4_2 // $d2=getOperand(0), $s=getOperand(1)
178 // CHECK-NEXT:     <<$mi.getOpcode() == MOV>>:$__anonpred4_1
179 // CHECK-NEXT:     <<$mi.getOpcode() == MOV>>:$__anonpred4_3
180 // CHECK-NEXT:     <<$mi0 == $mi1>>:$__anonpred4_4
181 // CHECK-NEXT:     __anon4_0 ==> __anonpred4_1[mi]
182 // CHECK-NEXT:     __anon4_2 ==> __anonpred4_3[mi]
183 // CHECK-NEXT:     __anon4_0[src1] ==> __anonpred4_4[mi0]
184 // CHECK-NEXT:     __anon4_2[src1] ==> __anonpred4_4[mi1]
185 // CHECK-NEXT: {{^}$}}
187 // CHECK-NEXT: digraph "multiref_use" {
188 // CHECK-NEXT:   rankdir="BT"
189 // CHECK-NEXT:   Node[[N1:(0x)?[0-9a-fA-F]+]] [shape=record,label="{{[{]{}}<s0>#0 $dst|<s1>#1 $src1}|__anon4_0|MOV|Match starts here|$d1=getOperand(0), $s=getOperand(1)|{{(0x)?[0-9a-fA-F]+}}|{<d0>#0 $dst|<d1>#1 $src1}}",color=red]
190 // CHECK-NEXT:   Node[[N2:(0x)?[0-9a-fA-F]+]] [shape=record,label="{{[{]{}}<s0>#0 $dst|<s1>#1 $src1}|__anon4_2|MOV|Match starts here|$d2=getOperand(0), $s=getOperand(1)|{{(0x)?[0-9a-fA-F]+}}|{<d0>#0 $dst|<d1>#1 $src1}}",color=red]
191 // CHECK-NEXT:   Pred[[P1:(0x)?[0-9a-fA-F]+]] [shape=record,label="{{[{]{}}<s0>#0 $$|<s1>#1 $mi}|__anonpred4_1|$mi.getOpcode() == MOV|{{(0x)?[0-9a-fA-F]+}}|{<d0>#0 $$|<d1>#1 $mi}}",style=dotted]
192 // CHECK-NEXT:   Pred[[P2:(0x)?[0-9a-fA-F]+]] [shape=record,label="{{[{]{}}<s0>#0 $$|<s1>#1 $mi}|__anonpred4_3|$mi.getOpcode() == MOV|{{(0x)?[0-9a-fA-F]+}}|{<d0>#0 $$|<d1>#1 $mi}}",style=dotted]
193 // CHECK-NEXT:   Pred[[P3:(0x)?[0-9a-fA-F]+]] [shape=record,label="{{[{]{}}<s0>#0 $$|<s1>#1 $mi0|<s2>#2 $mi1}|__anonpred4_4|$mi0 == $mi1|{{(0x)?[0-9a-fA-F]+}}|{<d0>#0 $$|<d1>#1 $mi0|<d2>#2 $mi1}}",style=dotted]
194 // CHECK-NEXT:   Node[[N1]]:e -> Pred[[P1]]:d1:s [style=dotted]
195 // CHECK-NEXT:   Node[[N2]]:e -> Pred[[P2]]:d1:s [style=dotted]
196 // CHECK-NEXT:   Node[[N1]]:s1:n -> Pred[[P3]]:d1:s [style=dotted]
197 // CHECK-NEXT:   Node[[N2]]:s1:n -> Pred[[P3]]:d2:s [style=dotted]
198 // CHECK-NEXT: {{^}$}}
200 def MyCombiner: GICombinerHelper<"GenMyCombiner", [
201   trivial,
202   simple,
203   multiroot,
204   nonstandardroot,
205   multiref_use
208 // Verify we're sharing operand lists correctly
209 // CHECK-LABEL: GIMatchDagOperandListContext {
210 // CHECK-NEXT:    OperandLists {
211 // CHECK-NEXT:      0:dst<def>, 1:src1{{$}}
212 // CHECK-NEXT:      0:$<def>, 1:mi{{$}}
213 // CHECK-NEXT:      0:$<def>, 1:mi0, 2:mi1{{$}}
214 // CHECK-NEXT:    }
215 // CHECK-NEXT:  }