xref: /llvm-project/llvm/test/TableGen/GlobalISelCombinerEmitter/pattern-errors.td (revision 7d81062352f75cf328d91d4900af52c1842b950e)
1// RUN: not llvm-tblgen -I %S/Inputs -I %p/../../../include -gen-global-isel-combiner \
2// RUN:     -combiners=MyCombiner %s 2>&1| \
3// RUN: FileCheck %s -implicit-check-not=error:
4
5include "llvm/Target/Target.td"
6include "llvm/Target/GlobalISel/Combine.td"
7
8include "test-intrinsics.td"
9
10def MyTargetISA : InstrInfo;
11def MyTarget : Target { let InstructionSet = MyTargetISA; }
12
13// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Cannot find root 'missing' in match patterns!
14def root_not_found : GICombineRule<
15  (defs root:$missing),
16  (match (COPY $a, $b):$d),
17  (apply [{ APPLY }])>;
18
19// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: apply pattern 'd' is supposed to be a root but it does not redefine any of the defs of the match root
20def misleading_root : GICombineRule<
21  (defs root:$d),
22  (match (COPY $a, $b):$d),
23  (apply (COPY $tmp, $b):$d,
24         (COPY $a, $tmp))>;
25
26// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: C++ code cannot be the root of a rule!
27def cxx_root : GICombineRule<
28  (defs root:$a),
29  (match "return MATCH":$a),
30  (apply [{ APPLY }]:$z)>;
31
32// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Cannot use live-in operand 'b' as match pattern root!
33def livein_root : GICombineRule<
34  (defs root:$b),
35  (match (COPY $a, $b)),
36  (apply [{ APPLY }])>;
37
38// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: 'COPY' expected 2 operands, got 1
39// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Failed to parse pattern: '(COPY ?:$a)'
40def not_enough_operands : GICombineRule<
41  (defs root:$d),
42  (match (COPY $a):$d),
43  (apply [{ APPLY }])>;
44
45// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: 'COPY' expected 2 operands, got 3
46// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Failed to parse pattern: '(COPY ?:$a, ?:$b, ?:$c)'
47def too_many_operands : GICombineRule<
48  (defs root:$d),
49  (match (COPY $a, $b, $c):$d),
50  (apply [{ APPLY }])>;
51
52// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Operand 'd' is defined multiple times in the 'match' patterns
53def multi_defs : GICombineRule<
54  (defs root:$d),
55  (match (COPY $d, $b), (COPY $d, $x)),
56  (apply [{ APPLY }])>;
57
58// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Operand 'd' is defined multiple times in the 'match' patterns
59def multi_defs_2 : GICombineRule<
60  (defs root:$d),
61  (match (G_UNMERGE_VALUES $d, $d, $b)),
62  (apply [{ APPLY }])>;
63
64// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: pattern 'foo' ('COPY') is unreachable from the pattern root!
65def unreachable_pat : GICombineRule<
66  (defs root:$d),
67  (match (COPY $a, $b):$d, (COPY $z, $k):$foo),
68  (apply [{ APPLY }])>;
69
70// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: 'applytest': wip_match_opcode is not supported in apply patterns
71def wip_match_opcode_in_apply : GICombineRule<
72  (defs root:$d),
73  (match (COPY $a, $b):$d, (wip_match_opcode G_ZEXT)),
74  (apply (wip_match_opcode G_ZEXT):$applytest)>;
75
76// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: wip_match_opcode can not be used with instruction patterns!
77def wip_match_opcode_with_inst_pat : GICombineRule<
78  (defs root:$d),
79  (match (COPY $a, $b):$d, (wip_match_opcode G_ZEXT)),
80  (apply [{ APPLY }])>;
81
82// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: wip_opcode_match can only be present once
83def multiple_wip_match_opcode : GICombineRule<
84  (defs root:$d),
85  (match (wip_match_opcode COPY):$d, (wip_match_opcode G_ZEXT)),
86  (apply [{ APPLY }])>;
87
88// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Operand 'a' is defined multiple times in the 'apply' patterns
89def multiple_def_in_apply : GICombineRule<
90  (defs root:$d),
91  (match (COPY $a, $b):$d),
92  (apply (COPY $a, $b), (COPY $a, $b))>;
93
94// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: 'd' match pattern defined more than once!
95def redef_match : GICombineRule<
96  (defs root:$d),
97  (match (COPY $a, $b):$d, (COPY $b, $z):$d),
98  (apply (COPY $a, $b))>;
99
100// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: 'o' apply pattern defined more than once!
101def redef_apply: GICombineRule<
102  (defs root:$d),
103  (match (COPY $a, $b):$d),
104  (apply (COPY $a, $x):$o, (COPY $x, $b):$o)>;
105
106// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: redefining an instruction other than the root is not supported (operand 'b'
107def redef_nonroot : GICombineRule<
108  (defs root:$a),
109  (match (COPY $a, $b), (COPY $b, $z)),
110  (apply (COPY $a, $b), (G_ZEXT $b, (i32 0)))>;
111
112// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Cannot define live-in operand 'b' in the 'apply' pattern
113def cannot_def_match_livein : GICombineRule<
114  (defs root:$d),
115  (match (COPY $a, $b):$d),
116  (apply (COPY $a, $b), (COPY $b, $b))>;
117
118// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: invalid output operand 'x': operand is not a live-in of the match pattern, and it has no definition
119def undef_in_apply : GICombineRule<
120  (defs root:$d),
121  (match (COPY $a, $b):$d),
122  (apply (COPY $a, $x))>;
123
124// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: 'a' must be redefined in the 'apply' pattern
125def no_redef_in_apply : GICombineRule<
126  (defs root:$a),
127  (match (COPY $a, $b):$foo),
128  (apply (COPY $x, $b))>;
129
130// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: 'b' must be redefined in the 'apply' pattern
131def no_redef_in_apply_multidefroot : GICombineRule<
132  (defs root:$a),
133  (match (G_UNMERGE_VALUES $a, $b, $c)),
134  (apply (COPY $a, $c))>;
135
136// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: cannot use wip_match_opcode in combination with apply instruction patterns
137def instpat_with_wipmatch : GICombineRule<
138  (defs root:$d),
139  (match (wip_match_opcode COPY):$d),
140  (apply (COPY $x, $b):$d)>;
141
142// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: cannot parse operand '(i32)'
143// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Failed to parse pattern: '(COPY ?:$x, (i32))
144def bad_imm_noarg : GICombineRule<
145  (defs root:$a),
146  (match (COPY $x, (i32)):$d),
147  (apply (COPY $x, $b):$d)>;
148
149// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: cannot parse operand '(i32 0, 0)'
150// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Failed to parse pattern: '(COPY ?:$x, (i32 0, 0))
151def bad_imm_too_many_args : GICombineRule<
152  (defs root:$a),
153  (match (COPY $x, (i32 0, 0)):$d),
154  (apply (COPY $x, $b):$d)>;
155
156// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: cannot parse immediate '(COPY 0)': unknown type 'COPY'
157// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Failed to parse pattern: '(COPY ?:$x, (COPY 0))
158def bad_imm_not_a_valuetype : GICombineRule<
159  (defs root:$a),
160  (match (COPY $x, (COPY 0)):$d),
161  (apply (COPY $x, $b):$d)>;
162
163// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: invalid output operand 'imm': output immediates cannot be named
164// CHECK: :[[@LINE+1]]:{{[0-9]+}}: note: while emitting pattern 'd' (COPY)
165def output_imm_cannot_be_named : GICombineRule<
166  (defs root:$x),
167  (match (COPY $x, (i32 0)):$d),
168  (apply (COPY $x, (i32 0):$imm):$d)>;
169
170// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: 'G_CONSTANT' immediate must be typed!
171// CHECK: :[[@LINE+1]]:{{[0-9]+}}: note: while emitting pattern 'd' (G_CONSTANT)
172def output_imm_must_be_typed : GICombineRule<
173  (defs root:$x),
174  (match (COPY $x, (i32 0)):$d),
175  (apply (G_CONSTANT $x, 0):$d)>;
176
177// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: 'G_BUILD_VECTOR' expected at least 2 operands, got 1
178// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Failed to parse pattern: '(G_BUILD_VECTOR ?:$x)'
179def too_few_ops_for_variadic : GICombineRule<
180  (defs root:$x),
181  (match (G_BUILD_VECTOR $x)),
182  (apply (COPY $x, 0))>;
183
184// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: expected an operand name after 'i32'
185// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Failed to parse pattern: '(G_FNEG ?:$x, i32)'
186def expected_op_name : GICombineRule<
187  (defs root:$x),
188  (match (G_FNEG $x, i32)),
189  (apply (COPY $x, (i32 0)))>;
190
191// CHECK: :[[@LINE+3]]:{{[0-9]+}}: error: cannot parse operand type: unknown type 'not_a_type'
192// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: Failed to parse pattern: '(G_FNEG ?:$x, not_a_type:$y)'
193def not_a_type;
194def bad_mo_type_not_a_valuetype : GICombineRule<
195  (defs root:$x),
196  (match (G_FNEG $x, not_a_type:$y)),
197  (apply (COPY $x, (i32 0)))>;
198
199// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: def of a new register 'newreg' in the apply patterns must have a type
200def untyped_new_reg_in_apply : GICombineRule<
201  (defs root:$x),
202  (match (G_FNEG $x, $y)),
203  (apply (COPY $newreg, (i32 0)),
204         (COPY $x, $newreg))>;
205
206// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: 'y' is a named immediate, it cannot be defined by another instruction
207// CHECK: :[[@LINE+1]]:{{[0-9]+}}: note: 'y' is defined by 'foo'
208def def_named_imm_match : GICombineRule<
209  (defs root:$x),
210  (match  (G_SEXT $y, $z):$foo,
211          (G_FNEG $x, (i32 0):$y)),
212  (apply (COPY $x, (i32 0)))>;
213
214// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: invalid output operand 'tmp': output immediates cannot be named
215// CHECK: :[[@LINE+1]]:{{[0-9]+}}: note: while emitting pattern 'foo' (COPY)
216def def_named_imm_apply : GICombineRule<
217  (defs root:$x),
218  (match (G_FNEG $x, $y)),
219  (apply (COPY i32:$tmp, $y),
220         (COPY $x, (i32 0):$tmp):$foo)>;
221
222// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: MIFlags can only be present once on an instruction
223// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Failed to parse pattern: '(G_ZEXT ?:$dst, ?:$src, (MIFlags FmArcp), (MIFlags FmArcp))'
224def multi_miflags : GICombineRule<
225  (defs root:$dst),
226  (match (G_ZEXT $dst, $src, (MIFlags FmArcp), (MIFlags FmArcp)):$mi),
227  (apply (G_MUL $dst, $src, $src))>;
228
229def NotAMIFlagEnum;
230
231// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: 'NotAMIFlagEnum' is not a subclass of 'MIFlagEnum'
232// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Failed to parse pattern: '(G_ZEXT ?:$dst, ?:$src, (MIFlags NotAMIFlagEnum))'
233def not_miflagenum_1 : GICombineRule<
234  (defs root:$dst),
235  (match (G_ZEXT $dst, $src, (MIFlags NotAMIFlagEnum)):$mi),
236  (apply (G_MUL $dst, $src, $src))>;
237
238// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: 'NotAMIFlagEnum' is not a subclass of 'MIFlagEnum'
239// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Failed to parse pattern: '(G_ZEXT ?:$dst, ?:$src, (MIFlags (not NotAMIFlagEnum)))'
240def not_miflagenum_2 : GICombineRule<
241  (defs root:$dst),
242  (match (G_ZEXT $dst, $src, (MIFlags (not NotAMIFlagEnum))):$mi),
243
244  (apply (G_MUL $dst, $src, $src))>;
245
246// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: matching/writing MIFlags is only allowed on CodeGenInstruction patterns
247// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Failed to parse pattern: '(GIReplaceReg ?:$x, ?:$y, (MIFlags FmArcp))'
248def miflags_in_builtin : GICombineRule<
249  (defs root:$x),
250  (match (COPY $x, $y)),
251  (apply (GIReplaceReg $x, $y, (MIFlags FmArcp)))>;
252
253// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: matching/writing MIFlags is only allowed on CodeGenInstruction patterns
254// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Failed to parse pattern: '(GIReplaceReg ?:$x, ?:$y, (MIFlags FmArcp))'
255def miflags_in_intrin : GICombineRule<
256  (defs root:$x),
257  (match (int_1in_1out $x, $y)),
258  (apply (GIReplaceReg $x, $y, (MIFlags FmArcp)))>;
259
260// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: 'match' patterns cannot refer to flags from other instructions
261// CHECK: :[[@LINE+1]]:{{[0-9]+}}: note: MIFlags in 'mi' refer to: impostor
262def using_flagref_in_match : GICombineRule<
263  (defs root:$dst),
264  (match (G_ZEXT $dst, $src, (MIFlags $impostor)):$mi),
265  (apply (G_MUL $dst, $src, $src))>;
266
267// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: unknown instruction '$impostor' referenced in MIFlags of '__badflagref_in_apply_apply_0'
268def badflagref_in_apply : GICombineRule<
269  (defs root:$dst),
270  (match (G_ZEXT $dst, $src):$mi),
271  (apply (G_MUL $dst, $src, $src, (MIFlags $impostor)))>;
272
273// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: 'apply' patterns cannot mix C++ code with other types of patterns
274def mixed_cxx_apply : GICombineRule<
275  (defs root:$dst),
276  (match (G_ZEXT $dst, $src):$mi),
277  (apply (G_MUL $dst, $src, $src), "APPLY")>;
278
279// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: GIDefMatchData can only be used if 'apply' in entirely written in C++
280def dummy_md : GIDefMatchData<"unsigned">;
281def matchdata_without_cxx_apply : GICombineRule<
282  (defs root:$dst, dummy_md:$md),
283  (match (G_ZEXT $dst, $src):$mi),
284  (apply (G_MUL $dst, $src, $src))>;
285
286// CHECK: error: Failed to parse one or more rules
287
288def MyCombiner: GICombiner<"GenMyCombiner", [
289  root_not_found,
290  misleading_root,
291  cxx_root,
292  livein_root,
293  not_enough_operands,
294  too_many_operands,
295  multi_defs,
296  multi_defs_2,
297  unreachable_pat,
298  wip_match_opcode_in_apply,
299  wip_match_opcode_with_inst_pat,
300  multiple_wip_match_opcode,
301  multiple_def_in_apply,
302  redef_match,
303  redef_apply,
304  redef_nonroot,
305  cannot_def_match_livein,
306  undef_in_apply,
307  no_redef_in_apply,
308  no_redef_in_apply_multidefroot,
309  instpat_with_wipmatch,
310  bad_imm_noarg,
311  bad_imm_too_many_args,
312  bad_imm_not_a_valuetype,
313  output_imm_cannot_be_named,
314  output_imm_must_be_typed,
315  too_few_ops_for_variadic,
316  expected_op_name,
317  bad_mo_type_not_a_valuetype,
318  untyped_new_reg_in_apply,
319  def_named_imm_match,
320  def_named_imm_apply,
321  multi_miflags,
322  not_miflagenum_1,
323  not_miflagenum_2,
324  miflags_in_builtin,
325  miflags_in_intrin,
326  using_flagref_in_match,
327  badflagref_in_apply,
328  mixed_cxx_apply,
329  matchdata_without_cxx_apply
330]>;
331