1 // RUN: llvm-tblgen -I %S/Inputs -I %p/../../../include -gen-global-isel-combiner \
2 // RUN: -gicombiner-stop-after-parse -combiners=MyCombiner %s | \
5 include "llvm/Target/Target.td"
6 include "llvm/Target/GlobalISel/Combine.td"
8 include "test-intrinsics.td"
10 def MyTargetISA : InstrInfo;
11 def MyTarget : Target { let InstructionSet = MyTargetISA; }
15 def HasAnswerToEverything : Predicate<"Subtarget->getAnswerToUniverse() == 42 && Subtarget->getAnswerToLife() == 42">;
16 def reg_matchinfo : GIDefMatchData<"Register">;
18 // CHECK: (CombineRule name:WipOpcodeTest0 id:0 root:d
19 // CHECK-NEXT: (MatchPats
20 // CHECK-NEXT: <match_root>d:(AnyOpcodePattern [G_TRUNC])
22 // CHECK-NEXT: (ApplyPats
23 // CHECK-NEXT: __WipOpcodeTest0_apply_0:(CXXPattern apply code:"APPLY")
25 // CHECK-NEXT: (OperandTable MatchPats <empty>)
26 // CHECK-NEXT: (OperandTable ApplyPats <empty>)
28 def WipOpcodeTest0 : GICombineRule<
30 (match (wip_match_opcode G_TRUNC):$d),
33 // CHECK: (CombineRule name:WipOpcodeTest1 id:1 root:d
34 // CHECK-NEXT: (MatchPats
35 // CHECK-NEXT: <match_root>d:(AnyOpcodePattern [G_TRUNC, G_SEXT])
37 // CHECK-NEXT: (ApplyPats
38 // CHECK-NEXT: __WipOpcodeTest1_apply_0:(CXXPattern apply code:"APPLY")
40 // CHECK-NEXT: (OperandTable MatchPats <empty>)
41 // CHECK-NEXT: (OperandTable ApplyPats <empty>)
43 def WipOpcodeTest1 : GICombineRule<
45 (match (wip_match_opcode G_TRUNC, G_SEXT):$d),
48 // CHECK: (CombineRule name:InstTest0 id:2 root:d
49 // CHECK-NEXT: (MatchPats
50 // CHECK-NEXT: <match_root>d:(CodeGenInstructionPattern COPY operands:[<def>$a, $b])
52 // CHECK-NEXT: (ApplyPats
53 // CHECK-NEXT: __InstTest0_apply_0:(CXXPattern apply code:"APPLY")
55 // CHECK-NEXT: (OperandTable MatchPats
57 // CHECK-NEXT: b -> <live-in>
59 // CHECK-NEXT: (OperandTable ApplyPats <empty>)
61 def InstTest0 : GICombineRule<
63 (match (COPY $a, $b):$d),
66 // CHECK: (CombineRule name:InstTest1 id:3 root:d
67 // CHECK-NEXT: (MatchDatas
68 // CHECK-NEXT: (MatchDataDef symbol:r0 type:Register)
70 // CHECK-NEXT: (MatchPats
71 // CHECK-NEXT: <match_root>d:(CodeGenInstructionPattern COPY operands:[<def>$a, i32:$b])
72 // CHECK-NEXT: __InstTest1_match_1:(CodeGenInstructionPattern G_ZEXT operands:[<def>$x, 0])
74 // CHECK-NEXT: (ApplyPats
75 // CHECK-NEXT: __InstTest1_apply_0:(CXXPattern apply code:"APPLY")
77 // CHECK-NEXT: (OperandTable MatchPats
79 // CHECK-NEXT: b -> <live-in>
80 // CHECK-NEXT: x -> __InstTest1_match_1
82 // CHECK-NEXT: (OperandTable ApplyPats <empty>)
84 let Predicates = [HasAnswerToEverything] in
85 def InstTest1 : GICombineRule<
86 (defs root:$d, reg_matchinfo:$r0),
87 (match (COPY $a, i32:$b):$d,
91 // CHECK: (CombineRule name:InstTest2 id:4 root:d
92 // CHECK-NEXT: (MatchDatas
93 // CHECK-NEXT: (MatchDataDef symbol:r0 type:Register)
95 // CHECK-NEXT: (MatchPats
96 // CHECK-NEXT: <match_root>__InstTest2_match_0:(CodeGenInstructionPattern COPY operands:[<def>$d, (i32 0):$x])
98 // CHECK-NEXT: (ApplyPats
99 // CHECK-NEXT: __InstTest2_apply_0:(CXXPattern apply code:"APPLY")
101 // CHECK-NEXT: (OperandTable MatchPats
102 // CHECK-NEXT: d -> __InstTest2_match_0
103 // CHECK-NEXT: x -> <live-in>
105 // CHECK-NEXT: (OperandTable ApplyPats <empty>)
107 def InstTest2 : GICombineRule<
108 (defs root:$d, reg_matchinfo:$r0),
109 (match (COPY $d, (i32 0):$x)),
110 (apply [{ APPLY }])>;
112 // CHECK: (CombineRule name:InOutInstTest0 id:5 root:dst
113 // CHECK-NEXT: (MatchPats
114 // CHECK-NEXT: <match_root>__InOutInstTest0_match_0:(CodeGenInstructionPattern COPY operands:[<def>$dst, $tmp])
115 // CHECK-NEXT: __InOutInstTest0_match_1:(CodeGenInstructionPattern G_ZEXT operands:[<def>$tmp, $src])
117 // CHECK-NEXT: (ApplyPats
118 // CHECK-NEXT: <apply_root>__InOutInstTest0_apply_0:(CodeGenInstructionPattern G_TRUNC operands:[<def>$dst, $src])
120 // CHECK-NEXT: (OperandTable MatchPats
121 // CHECK-NEXT: dst -> __InOutInstTest0_match_0
122 // CHECK-NEXT: src -> <live-in>
123 // CHECK-NEXT: tmp -> __InOutInstTest0_match_1
125 // CHECK-NEXT: (OperandTable ApplyPats
126 // CHECK-NEXT: dst -> __InOutInstTest0_apply_0
127 // CHECK-NEXT: src -> <live-in>
130 def InOutInstTest0 : GICombineRule<
132 (match (COPY $dst, $tmp),
133 (G_ZEXT $tmp, $src)),
134 (apply (G_TRUNC $dst, $src))>;
136 def MatchICst: GICombinePatFrag<
138 (ins gi_mo:$foo, gi_imm:$cst),
139 [(pattern "return matchIConstant(${foo}, ${cst})")]>;
141 // CHECK: (CombineRule name:PatFragTest0 id:6 root:dst
142 // CHECK-NEXT: (PatFrags
143 // CHECK-NEXT: (PatFrag name:MatchICst
144 // CHECK-NEXT: (ins [foo:machine_operand, cst:imm])
145 // CHECK-NEXT: (alternatives [
147 // CHECK-NEXT: (CXXPattern name:__MatchICst_alt0_pattern_0 match code:"return matchIConstant(${foo}, ${cst})"),
152 // CHECK-NEXT: (MatchPats
153 // CHECK-NEXT: <match_root>__PatFragTest0_match_0:(CodeGenInstructionPattern G_ZEXT operands:[<def>$dst, $cst])
154 // CHECK-NEXT: __PatFragTest0_match_1:(PatFragPattern MatchICst operands:[$cst, (i32 0)])
156 // CHECK-NEXT: (ApplyPats
157 // CHECK-NEXT: <apply_root>__PatFragTest0_apply_0:(CodeGenInstructionPattern COPY operands:[<def>$dst, (i32 0)])
159 // CHECK-NEXT: (OperandTable MatchPats
160 // CHECK-NEXT: cst -> <live-in>
161 // CHECK-NEXT: dst -> __PatFragTest0_match_0
163 // CHECK-NEXT: (OperandTable ApplyPats
164 // CHECK-NEXT: dst -> __PatFragTest0_apply_0
167 def PatFragTest0 : GICombineRule<
169 (match (G_ZEXT $dst, $cst), (MatchICst $cst, (i32 0))),
170 (apply (COPY $dst, (i32 0)))>;
172 def MatchFooPerms: GICombinePatFrag<
174 (ins gi_mo:$foo, gi_imm:$cst),
176 (pattern "return foo(${foo}, ${cst})"),
177 (pattern "return bar(${foo}, ${cst})"),
178 (pattern "return bux(${foo}, ${cst})"),
181 // CHECK: (CombineRule name:PatFragTest1 id:7 root:dst
182 // CHECK-NEXT: (PatFrags
183 // CHECK-NEXT: (PatFrag name:MatchFooPerms
184 // CHECK-NEXT: (ins [foo:machine_operand, cst:imm])
185 // CHECK-NEXT: (alternatives [
187 // CHECK-NEXT: (CXXPattern name:__MatchFooPerms_alt0_pattern_0 match code:"return foo(${foo}, ${cst})"),
190 // CHECK-NEXT: (CXXPattern name:__MatchFooPerms_alt1_pattern_0 match code:"return bar(${foo}, ${cst})"),
193 // CHECK-NEXT: (CXXPattern name:__MatchFooPerms_alt2_pattern_0 match code:"return bux(${foo}, ${cst})"),
198 // CHECK-NEXT: (MatchPats
199 // CHECK-NEXT: <match_root>__PatFragTest1_match_0:(CodeGenInstructionPattern G_ZEXT operands:[<def>$dst, $cst])
200 // CHECK-NEXT: a:(PatFragPattern MatchFooPerms operands:[$cst, (i32 0)])
201 // CHECK-NEXT: b:(PatFragPattern MatchFooPerms operands:[$cst, (i32 0)])
202 // CHECK-NEXT: c:(PatFragPattern MatchFooPerms operands:[$cst, (i32 0)])
204 // CHECK-NEXT: (ApplyPats
205 // CHECK-NEXT: <apply_root>__PatFragTest1_apply_0:(CodeGenInstructionPattern COPY operands:[<def>$dst, (i32 0)])
207 // CHECK-NEXT: (OperandTable MatchPats
208 // CHECK-NEXT: cst -> <live-in>
209 // CHECK-NEXT: dst -> __PatFragTest1_match_0
211 // CHECK-NEXT: (OperandTable ApplyPats
212 // CHECK-NEXT: dst -> __PatFragTest1_apply_0
214 // CHECK-NEXT: (PermutationsToEmit
215 // CHECK-NEXT: [a[0], b[0], c[0]],
216 // CHECK-NEXT: [a[0], b[0], c[1]],
217 // CHECK-NEXT: [a[0], b[0], c[2]],
218 // CHECK-NEXT: [a[0], b[1], c[0]],
219 // CHECK-NEXT: [a[0], b[1], c[1]],
220 // CHECK-NEXT: [a[0], b[1], c[2]],
221 // CHECK-NEXT: [a[0], b[2], c[0]],
222 // CHECK-NEXT: [a[0], b[2], c[1]],
223 // CHECK-NEXT: [a[0], b[2], c[2]],
224 // CHECK-NEXT: [a[1], b[0], c[0]],
225 // CHECK-NEXT: [a[1], b[0], c[1]],
226 // CHECK-NEXT: [a[1], b[0], c[2]],
227 // CHECK-NEXT: [a[1], b[1], c[0]],
228 // CHECK-NEXT: [a[1], b[1], c[1]],
229 // CHECK-NEXT: [a[1], b[1], c[2]],
230 // CHECK-NEXT: [a[1], b[2], c[0]],
231 // CHECK-NEXT: [a[1], b[2], c[1]],
232 // CHECK-NEXT: [a[1], b[2], c[2]],
233 // CHECK-NEXT: [a[2], b[0], c[0]],
234 // CHECK-NEXT: [a[2], b[0], c[1]],
235 // CHECK-NEXT: [a[2], b[0], c[2]],
236 // CHECK-NEXT: [a[2], b[1], c[0]],
237 // CHECK-NEXT: [a[2], b[1], c[1]],
238 // CHECK-NEXT: [a[2], b[1], c[2]],
239 // CHECK-NEXT: [a[2], b[2], c[0]],
240 // CHECK-NEXT: [a[2], b[2], c[1]],
241 // CHECK-NEXT: [a[2], b[2], c[2]],
244 let MaxPermutations = -1 in
245 def PatFragTest1 : GICombineRule<
247 (match (G_ZEXT $dst, $cst),
248 (MatchFooPerms $cst, (i32 0)):$a,
249 (MatchFooPerms $cst, (i32 0)):$b,
250 (MatchFooPerms $cst, (i32 0)):$c
252 (apply (COPY $dst, (i32 0)))>;
254 // CHECK: (CombineRule name:VariadicsInTest id:8 root:dst
255 // CHECK-NEXT: (MatchPats
256 // CHECK-NEXT: <match_root>__VariadicsInTest_match_0:(CodeGenInstructionPattern G_BUILD_VECTOR operands:[<def>$dst, $a, $b])
258 // CHECK-NEXT: (ApplyPats
259 // CHECK-NEXT: <apply_root>__VariadicsInTest_apply_0:(CodeGenInstructionPattern COPY operands:[<def>$dst, (i32 0)])
261 // CHECK-NEXT: (OperandTable MatchPats
262 // CHECK-NEXT: a -> <live-in>
263 // CHECK-NEXT: b -> <live-in>
264 // CHECK-NEXT: dst -> __VariadicsInTest_match_0
266 // CHECK-NEXT: (OperandTable ApplyPats
267 // CHECK-NEXT: dst -> __VariadicsInTest_apply_0
270 def VariadicsInTest : GICombineRule<
272 (match (G_BUILD_VECTOR $dst, $a, $b)),
273 (apply (COPY $dst, (i32 0)))>;
275 // CHECK: (CombineRule name:VariadicsOutTest id:9 root:a
276 // CHECK-NEXT: (MatchPats
277 // CHECK-NEXT: <match_root>__VariadicsOutTest_match_0:(CodeGenInstructionPattern G_UNMERGE_VALUES operands:[<def>$a, <def>$b, $src])
279 // CHECK-NEXT: (ApplyPats
280 // CHECK-NEXT: <apply_root>__VariadicsOutTest_apply_0:(CodeGenInstructionPattern COPY operands:[<def>$a, (i32 0)])
281 // CHECK-NEXT: <apply_root>__VariadicsOutTest_apply_1:(CodeGenInstructionPattern COPY operands:[<def>$b, (i32 0)])
283 // CHECK-NEXT: (OperandTable MatchPats
284 // CHECK-NEXT: a -> __VariadicsOutTest_match_0
285 // CHECK-NEXT: b -> __VariadicsOutTest_match_0
286 // CHECK-NEXT: src -> <live-in>
288 // CHECK-NEXT: (OperandTable ApplyPats
289 // CHECK-NEXT: a -> __VariadicsOutTest_apply_0
290 // CHECK-NEXT: b -> __VariadicsOutTest_apply_1
293 def VariadicsOutTest : GICombineRule<
295 (match (G_UNMERGE_VALUES $a, $b, $src)),
296 (apply (COPY $a, (i32 0)),
297 (COPY $b, (i32 0)))>;
299 // CHECK: (CombineRule name:TypeOfTest id:10 root:dst
300 // CHECK-NEXT: (MatchPats
301 // CHECK-NEXT: <match_root>__TypeOfTest_match_0:(CodeGenInstructionPattern COPY operands:[<def>$dst, $tmp])
302 // CHECK-NEXT: __TypeOfTest_match_1:(CodeGenInstructionPattern G_ZEXT operands:[<def>$tmp, $src])
304 // CHECK-NEXT: (ApplyPats
305 // CHECK-NEXT: <apply_root>__TypeOfTest_apply_0:(CodeGenInstructionPattern G_MUL operands:[<def>$dst, (GITypeOf<$src> 0), (GITypeOf<$dst> -1)])
307 // CHECK-NEXT: (OperandTable MatchPats
308 // CHECK-NEXT: dst -> __TypeOfTest_match_0
309 // CHECK-NEXT: src -> <live-in>
310 // CHECK-NEXT: tmp -> __TypeOfTest_match_1
312 // CHECK-NEXT: (OperandTable ApplyPats
313 // CHECK-NEXT: dst -> __TypeOfTest_apply_0
316 def TypeOfTest : GICombineRule<
318 (match (COPY $dst, $tmp),
319 (G_ZEXT $tmp, $src)),
320 (apply (G_MUL $dst, (GITypeOf<"$src"> 0), (GITypeOf<"$dst"> -1)))>;
323 // CHECK: (CombineRule name:MIFlagsTest id:11 root:dst
324 // CHECK-NEXT: (MatchPats
325 // CHECK-NEXT: <match_root>mi:(CodeGenInstructionPattern G_ZEXT operands:[<def>$dst, $src] (MIFlags (set MachineInstr::FmReassoc) (unset MachineInstr::FmNoNans, MachineInstr::FmArcp)))
327 // CHECK-NEXT: (ApplyPats
328 // CHECK-NEXT: <apply_root>__MIFlagsTest_apply_0:(CodeGenInstructionPattern G_MUL operands:[<def>$dst, $src, $src] (MIFlags (set MachineInstr::FmReassoc) (unset MachineInstr::FmNsz, MachineInstr::FmArcp) (copy mi)))
330 // CHECK-NEXT: (OperandTable MatchPats
331 // CHECK-NEXT: dst -> mi
332 // CHECK-NEXT: src -> <live-in>
334 // CHECK-NEXT: (OperandTable ApplyPats
335 // CHECK-NEXT: dst -> __MIFlagsTest_apply_0
336 // CHECK-NEXT: src -> <live-in>
339 def MIFlagsTest : GICombineRule<
341 (match (G_ZEXT $dst, $src, (MIFlags FmReassoc, (not FmNoNans, FmArcp))):$mi),
342 (apply (G_MUL $dst, $src, $src, (MIFlags $mi, FmReassoc, (not FmNsz, FmArcp))))>;
344 // CHECK-NEXT: (CombineRule name:IntrinTest0 id:12 root:a
345 // CHECK-NEXT: (MatchPats
346 // CHECK-NEXT: <match_root>__IntrinTest0_match_0:(CodeGenInstructionPattern G_INTRINSIC operands:[<def>$a, $b] intrinsic(@llvm.1in.1out))
348 // CHECK-NEXT: (ApplyPats
349 // CHECK-NEXT: <apply_root>__IntrinTest0_apply_0:(CodeGenInstructionPattern G_INTRINSIC_W_SIDE_EFFECTS operands:[<def>$a, $b] intrinsic(@llvm.sideeffects.1in.1out))
351 // CHECK-NEXT: (OperandTable MatchPats
352 // CHECK-NEXT: a -> __IntrinTest0_match_0
353 // CHECK-NEXT: b -> <live-in>
355 // CHECK-NEXT: (OperandTable ApplyPats
356 // CHECK-NEXT: a -> __IntrinTest0_apply_0
357 // CHECK-NEXT: b -> <live-in>
360 def IntrinTest0 : GICombineRule<
362 (match (int_1in_1out $a, $b)),
363 (apply (int_sideeffects_1in_1out $a, $b))>;
365 // CHECK: (CombineRule name:IntrinTest1 id:13 root:a
366 // CHECK-NEXT: (MatchPats
367 // CHECK-NEXT: <match_root>__IntrinTest1_match_0:(CodeGenInstructionPattern G_INTRINSIC_CONVERGENT operands:[<def>$a, $b] intrinsic(@llvm.convergent.1in.1out))
369 // CHECK-NEXT: (ApplyPats
370 // CHECK-NEXT: <apply_root>__IntrinTest1_apply_0:(CodeGenInstructionPattern G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS operands:[<def>$a, $b] intrinsic(@llvm.convergent.sideeffects.1in.1out))
372 // CHECK-NEXT: (OperandTable MatchPats
373 // CHECK-NEXT: a -> __IntrinTest1_match_0
374 // CHECK-NEXT: b -> <live-in>
376 // CHECK-NEXT: (OperandTable ApplyPats
377 // CHECK-NEXT: a -> __IntrinTest1_apply_0
378 // CHECK-NEXT: b -> <live-in>
381 def IntrinTest1 : GICombineRule<
383 (match (int_convergent_1in_1out $a, $b)),
384 (apply (int_convergent_sideeffects_1in_1out $a, $b))>;
386 def MyCombiner: GICombiner<"GenMyCombiner", [