[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / TableGen / GICombinerEmitter / match-tree.td
blobfc911fb2f29c52722164c54eda13affae1f72daa
1 // RUN: llvm-tblgen -I %p/../../../include -gen-global-isel-combiner \
2 // RUN:     -combiners=MyCombinerHelper -gicombiner-stop-after-build %s \
3 // RUN:     -o %t.inc | FileCheck %s
5 include "llvm/Target/Target.td"
6 include "llvm/Target/GlobalISel/Combine.td"
8 def MyTargetISA : InstrInfo;
9 def MyTarget : Target { let InstructionSet = MyTargetISA; }
11 def dummy;
13 def R0 : Register<"r0"> { let Namespace = "MyTarget"; }
14 def GPR32 : RegisterClass<"MyTarget", [i32], 32, (add R0)>;
15 class I<dag OOps, dag IOps, list<dag> Pat>
16   : Instruction {
17   let Namespace = "MyTarget";
18   let OutOperandList = OOps;
19   let InOperandList = IOps;
20   let Pattern = Pat;
22 def MOV : I<(outs GPR32:$dst), (ins GPR32:$src1), []>;
23 def ADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2), []>;
24 def SUB : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2), []>;
25 def MUL : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2), []>;
26 def TRUNC : I<(outs GPR32:$dst), (ins GPR32:$src1), []>;
27 def SEXT : I<(outs GPR32:$dst), (ins GPR32:$src1), []>;
28 def ZEXT : I<(outs GPR32:$dst), (ins GPR32:$src1), []>;
30 def Rule0 : GICombineRule<
31   (defs root:$d),
32   (match (MUL $t, $s1, $s2),
33          (SUB $d, $t, $s3)),
34   (apply [{ APPLY }])>;
36 def Rule1 : GICombineRule<
37   (defs root:$d),
38   (match (MOV $s1, $s2),
39          (MOV $d, $s1)),
40   (apply [{ APPLY }])>;
42 def Rule2 : GICombineRule<
43   (defs root:$d),
44   (match (MOV $d, $s)),
45   (apply [{ APPLY }])>;
47 def Rule3 : GICombineRule<
48   (defs root:$d),
49   (match (MUL $t, $s1, $s2),
50          (ADD $d, $t, $s3), [{ A }]),
51   (apply [{ APPLY }])>;
53 def Rule4 : GICombineRule<
54   (defs root:$d),
55   (match (ADD $d, $s1, $s2)),
56   (apply [{ APPLY }])>;
58 def Rule5 : GICombineRule<
59   (defs root:$d),
60   (match (SUB $d, $s1, $s2)),
61   (apply [{ APPLY }])>;
63 def Rule6 : GICombineRule<
64   (defs root:$d),
65   (match (SEXT $t, $s1),
66          (TRUNC $d, $t)),
67   (apply [{ APPLY }])>;
69 def Rule7 : GICombineRule<
70   (defs root:$d),
71   (match (ZEXT $t, $s1),
72          (TRUNC $d, $t)),
73   (apply [{ APPLY }])>;
75 def MyCombinerHelper: GICombinerHelper<"GenMyCombinerHelper", [
76   Rule0,
77   Rule1,
78   Rule2,
79   Rule3,
80   Rule4,
81   Rule5,
82   Rule6,
83   Rule7
84 ]>;
86 // CHECK-LABEL: digraph "matchtree" {
87 // CHECK-DAG:   Node[[N0:(0x)?[0-9a-fA-F]+]] [shape=record,label="{MI[0].getOpcode()|4 partitions|Rule0,Rule1,Rule2,Rule3,Rule4,Rule5,Rule6,Rule7}"]
88 // CHECK-DAG:   Node[[N1:(0x)?[0-9a-fA-F]+]] [shape=record,label="{MI[1] = getVRegDef(MI[0].getOperand(1))|2 partitions|Rule0,Rule5}"]
89 // CHECK-DAG:   Node[[N2:(0x)?[0-9a-fA-F]+]] [shape=record,label="{MI[1].getOpcode()|2 partitions|Rule0,Rule5}"]
90 // CHECK-DAG:   Node[[N3:(0x)?[0-9a-fA-F]+]] [shape=record,label="{No partitioner|Rule0}"]
91 // CHECK-DAG:   Node[[N4:(0x)?[0-9a-fA-F]+]] [shape=record,label="{No partitioner|Rule5}"]
92 // CHECK-DAG:   Node[[N5:(0x)?[0-9a-fA-F]+]] [shape=record,label="{No partitioner|Rule5}"]
93 // CHECK-DAG:   Node[[N6:(0x)?[0-9a-fA-F]+]] [shape=record,label="{MI[1] = getVRegDef(MI[0].getOperand(1))|2 partitions|Rule1,Rule2}"]
94 // CHECK-DAG:   Node[[N7:(0x)?[0-9a-fA-F]+]] [shape=record,label="{MI[1].getOpcode()|2 partitions|Rule1,Rule2}"]
95 // CHECK-DAG:   Node[[N8:(0x)?[0-9a-fA-F]+]] [shape=record,label="{No partitioner|Rule1}"]
96 // CHECK-DAG:   Node[[N9:(0x)?[0-9a-fA-F]+]] [shape=record,label="{No partitioner|Rule2}"]
97 // CHECK-DAG:   Node[[N10:(0x)?[0-9a-fA-F]+]] [shape=record,label="{No partitioner|Rule2}"]
98 // CHECK-DAG:   Node[[N11:(0x)?[0-9a-fA-F]+]] [shape=record,label="{MI[1] = getVRegDef(MI[0].getOperand(1))|2 partitions|Rule3,Rule4}"]
99 // CHECK-DAG:   Node[[N12:(0x)?[0-9a-fA-F]+]] [shape=record,label="{MI[1].getOpcode()|2 partitions|Rule3,Rule4}"]
100 // CHECK-DAG:   Node[[N13:(0x)?[0-9a-fA-F]+]] [shape=record,label="{No partitioner|Rule3,Rule4}",color=red]
101 // CHECK-DAG:   Node[[N14:(0x)?[0-9a-fA-F]+]] [shape=record,label="{No partitioner|Rule4}"]
102 // CHECK-DAG:   Node[[N15:(0x)?[0-9a-fA-F]+]] [shape=record,label="{No partitioner|Rule4}"]
103 // CHECK-DAG:   Node[[N16:(0x)?[0-9a-fA-F]+]] [shape=record,label="{MI[1] = getVRegDef(MI[0].getOperand(1))|1 partitions|Rule6,Rule7}"]
104 // CHECK-DAG:   Node[[N17:(0x)?[0-9a-fA-F]+]] [shape=record,label="{MI[1].getOpcode()|2 partitions|Rule6,Rule7}"]
105 // CHECK-DAG:   Node[[N18:(0x)?[0-9a-fA-F]+]] [shape=record,label="{No partitioner|Rule6}"]
106 // CHECK-DAG:   Node[[N19:(0x)?[0-9a-fA-F]+]] [shape=record,label="{No partitioner|Rule7}"]
108 // The most important partitioner is on the first opcode:
109 // CHECK-DAG:   Node[[N0]] -> Node[[N1]] [label="#0 MyTarget::SUB"]
110 // CHECK-DAG:   Node[[N0]] -> Node[[N6]] [label="#1 MyTarget::MOV"]
111 // CHECK-DAG:   Node[[N0]] -> Node[[N11]] [label="#2 MyTarget::ADD"]
112 // CHECK-DAG:   Node[[N0]] -> Node[[N16]] [label="#3 MyTarget::TRUNC"]
114 // For, MI[0].getOpcode() == SUB, then has to determine whether it has a reg
115 // operand and follow that link. If it can't then Rule5 is the only choice as
116 // that rule is not constrained to a reg.
117 // CHECK-DAG:   Node[[N1]] -> Node[[N2]] [label="#0 true"]
118 // CHECK-DAG:   Node[[N1]] -> Node[[N5]] [label="#1 false"]
120 // For, MI[0].getOpcode() == SUB && MI[0].getOperand(1).isReg(), if MI[1] is a
121 // MUL then it must be either Rule0 or Rule5. Rule0 is fully tested so Rule5 is
122 // unreachable. If it's not MUL then it must be Rule5.
123 // CHECK-DAG:   Node[[N2]] -> Node[[N3]] [label="#0 MyTarget::MUL"]
124 // CHECK-DAG:   Node[[N2]] -> Node[[N4]] [label="#1 * or nullptr"]
126 // CHECK-DAG:   Node[[N6]] -> Node[[N7]] [label="#0 true"]
127 // CHECK-DAG:   Node[[N6]] -> Node[[N10]] [label="#1 false"]
129 // CHECK-DAG:   Node[[N7]] -> Node[[N8]] [label="#0 MyTarget::MOV"]
130 // CHECK-DAG:   Node[[N7]] -> Node[[N9]] [label="#1 * or nullptr"]
132 // CHECK-DAG:   Node[[N11]] -> Node[[N12]] [label="#0 true"]
133 // CHECK-DAG:   Node[[N11]] -> Node[[N15]] [label="#1 false"]
135 // CHECK-DAG:   Node[[N12]] -> Node[[N13]] [label="#0 MyTarget::MUL"]
136 // CHECK-DAG:   Node[[N12]] -> Node[[N14]] [label="#1 * or nullptr"]
138 // CHECK-DAG:   Node[[N16]] -> Node[[N17]] [label="#0 true"]
140 // CHECK-DAG:   Node[[N17]] -> Node[[N18]] [label="#0 MyTarget::SEXT"]
141 // CHECK-DAG:   Node[[N17]] -> Node[[N19]] [label="#1 MyTarget::ZEXT"]
142 // CHECK-LABEL: {{^}$}}