xref: /llvm-project/llvm/test/TableGen/GlobalISelCombinerEmitter/patfrag-errors.td (revision 7d81062352f75cf328d91d4900af52c1842b950e)
1// RUN: not llvm-tblgen -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
8def MyTargetISA : InstrInfo;
9def MyTarget : Target { let InstructionSet = MyTargetISA; }
10
11def dummy;
12
13def MatchFooPerms: GICombinePatFrag<
14    (outs),
15    (ins gi_mo:$foo, gi_imm:$cst),
16    [
17      (pattern "return foo(${foo}, ${cst})"),
18      (pattern "return bar(${foo}, ${cst})"),
19      (pattern "return bux(${foo}, ${cst})"),
20    ]>;
21
22// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: cannot emit rule 'too_many_perms'; 27 permutations would be emitted, but the max is 16
23let MaxPermutations = 16 in
24def too_many_perms : GICombineRule<
25  (defs root:$dst),
26  (match (G_ZEXT $dst, $cst),
27         (MatchFooPerms $cst, (i32 0)):$a,
28         (MatchFooPerms $cst, (i32 0)):$b,
29         (MatchFooPerms $cst, (i32 0)):$c
30  ),
31  (apply (COPY $dst, (i32 0)))>;
32
33def DummyCXXPF: GICombinePatFrag<
34    (outs),
35    (ins gi_mo:$in),
36    [
37      (pattern "return foo()"),
38    ]>;
39// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: operand 'foo' (for parameter 'in' of 'DummyCXXPF') cannot be unbound
40// CHECK: :[[@LINE+1]]:{{[0-9]+}}: note: one or more alternatives of 'DummyCXXPF' do not bind 'in' to an instruction operand; either use a bound operand or ensure 'DummyCXXPF' binds 'in' in all alternatives
41def undef_livein : GICombineRule<
42  (defs root:$dst),
43  (match (G_ZEXT $dst, $bar),
44         (DummyCXXPF $foo)
45  ),
46  (apply (COPY $dst, (i32 0)))>;
47
48// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: GICombinePatFrag must have one root in its 'out' operands
49// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Could not parse GICombinePatFrag 'OutMustBeRoot'
50def OutMustBeRoot: GICombinePatFrag<
51    (outs $foo, $bar),
52    (ins),
53    [
54      (pattern (G_ZEXT $foo, $bar), (G_FPEXT $bar, $y)),
55    ]>;
56// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Failed to parse pattern: '(OutMustBeRoot ?:$bar, ?:$foo)'
57def out_must_be_root : GICombineRule<
58  (defs root:$dst),
59  (match (G_ZEXT $dst, $bar),
60         (OutMustBeRoot $bar, $foo)
61  ),
62  (apply (COPY $dst, (i32 0)))>;
63
64// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: output parameter 'bar' must be 'root' or 'gi_mo'
65// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Could not parse GICombinePatFrag 'BadOutType'
66def BadOutType: GICombinePatFrag<
67    (outs root:$foo, gi_imm:$bar),
68    (ins),
69    [
70      (pattern (G_ZEXT $foo, $bar), (G_FPEXT $bar, $y)),
71    ]>;
72// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Failed to parse pattern: '(BadOutType ?:$bar, ?:$foo)'
73def bad_out_type : GICombineRule<
74  (defs root:$dst),
75  (match (G_ZEXT $dst, $bar),
76         (BadOutType $bar, $foo)
77  ),
78  (apply (COPY $dst, (i32 0)))>;
79
80// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: pattern 'dbg' ('G_FPEXT') is unreachable from the pattern root!
81def UnreachablePat: GICombinePatFrag<
82    (outs root:$foo, $bar),
83    (ins),
84    [
85      (pattern (G_ZEXT $foo, $x), (G_FPEXT $bar, $y):$dbg),
86    ]>;
87def unreachable_pat : GICombineRule<
88  (defs root:$dst),
89  (match (G_ZEXT $dst, $bar),
90         (UnreachablePat $bar, $foo)
91  ),
92  (apply (COPY $dst, (i32 0)))>;
93
94// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: wip_match_opcode cannot be used in GICombinePatFrag
95// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Could not parse GICombinePatFrag 'WipMatchOpcodePatFrag'
96def WipMatchOpcodePatFrag: GICombinePatFrag<
97    (outs),
98    (ins),
99    [
100      (pattern (wip_match_opcode G_ZEXT)),
101    ]>;
102// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Failed to parse pattern: '(WipMatchOpcodePatFrag)'
103def wip_match_opcode_patfrag : GICombineRule<
104  (defs root:$dst),
105  (match (WipMatchOpcodePatFrag)),
106  (apply (COPY $dst, (i32 0)))>;
107
108def DummyPF: GICombinePatFrag<(outs),(ins),[]>;
109// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: nested GICombinePatFrag are not supported
110// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Could not parse GICombinePatFrag 'NestingPatFrag'
111def NestingPatFrag: GICombinePatFrag<
112    (outs),
113    (ins),
114    [
115      (pattern (DummyPF)),
116    ]>;
117// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Failed to parse pattern: '(NestingPatFrag)'
118def nest_pat_frag : GICombineRule<
119  (defs root:$dst),
120  (match (NestingPatFrag)),
121  (apply (COPY $dst, (i32 0)))>;
122
123// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: input parameter 'k' cannot be redefined!
124// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Could not parse GICombinePatFrag 'DupParamIn'
125def DupParamIn: GICombinePatFrag<
126    (outs),
127    (ins gi_mo:$k, gi_mo:$k),
128    [
129      (pattern (G_ZEXT $k, $x)),
130    ]>;
131// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Failed to parse pattern: '(DupParamIn ?:$dst, ?:$bar)'
132def dup_params_in : GICombineRule<
133  (defs root:$dst),
134  (match (DupParamIn $dst, $bar)),
135  (apply (COPY $dst, (i32 0)))>;
136
137// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: duplicate parameter 'k'
138// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Could not parse GICombinePatFrag 'DupParamOut'
139def DupParamOut: GICombinePatFrag<
140  (outs root:$k, root:$k),
141  (ins),
142  [
143    (pattern (G_ZEXT $k, $x)),
144  ]>;
145// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Failed to parse pattern: '(DupParamOut ?:$dst, ?:$bar)'
146def dup_params_out : GICombineRule<
147  (defs root:$dst),
148  (match (DupParamOut $dst, $bar)),
149  (apply (COPY $dst, (i32 0)))>;
150
151// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: input parameter 'k' cannot be redefined!
152// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Could not parse GICombinePatFrag 'DupParamInOut'
153def DupParamInOut: GICombinePatFrag<
154  (outs root:$k),
155  (ins gi_mo:$k),
156  [
157    (pattern (G_ZEXT $k, $x)),
158  ]>;
159// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Failed to parse pattern: '(DupParamInOut ?:$dst, ?:$bar)'
160def dup_params_inout : GICombineRule<
161  (defs root:$dst),
162  (match (DupParamInOut $dst, $bar)),
163  (apply (COPY $dst, (i32 0)))>;
164
165// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: output parameter 'k' must be defined by all alternative patterns in 'DefByAllAlts'
166// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Could not parse GICombinePatFrag 'DefByAllAlts'
167def DefByAllAlts: GICombinePatFrag<
168  (outs root:$k),
169  (ins),
170  [
171    (pattern (G_ZEXT $k, $x)),
172    (pattern (G_FPEXT $z, $k))
173  ]>;
174// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Failed to parse pattern: '(DefByAllAlts ?:$dst)'
175def def_by_all_alts : GICombineRule<
176  (defs root:$dst),
177  (match (DefByAllAlts $dst)),
178  (apply (COPY $dst, (i32 0)))>;
179
180// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: Operand 'x' is defined multiple times in patterns of alternative #1
181// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Could not parse GICombinePatFrag 'MultiDefInPat'
182def MultiDefInPat: GICombinePatFrag<
183  (outs root:$k),
184  (ins),
185  [
186    (pattern (G_ZEXT $k, $a)),
187    (pattern (G_ZEXT $k, $x), (G_ZEXT $x, $foo), (G_FPEXT $x, $foo)),
188  ]>;
189// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Failed to parse pattern: '(MultiDefInPat ?:$dst)'
190def multi_def_in_pat : GICombineRule<
191  (defs root:$dst),
192  (match (MultiDefInPat $dst)),
193  (apply (COPY $dst, (i32 0)))>;
194
195def ExpectedImm: GICombinePatFrag<
196  (outs root:$k),
197  (ins gi_imm:$i),
198  [
199    (pattern (G_ZEXT $k, $i)),
200  ]>;
201// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: expected operand 1 of 'ExpectedImm' to be an immediate; got MachineOperand $z
202// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Failed to parse pattern: '(ExpectedImm ?:$dst, ?:$z)'
203def expected_imm : GICombineRule<
204  (defs root:$dst),
205  (match (ExpectedImm $dst, $z)),
206  (apply (COPY $dst, (i32 0)))>;
207
208// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: operand 1 of 'ExpectedImm' cannot be a named immediate
209// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Failed to parse pattern: '(ExpectedImm ?:$dst, (i32 0):$z)'
210def expected_imm_namedimm : GICombineRule<
211  (defs root:$dst),
212  (match (ExpectedImm $dst, (i32 0):$z)),
213  (apply (COPY $dst, (i32 0)))>;
214
215def ExpectedMO: GICombinePatFrag<
216  (outs root:$k),
217  (ins gi_mo:$i),
218  [
219    (pattern (G_ZEXT $k, $i)),
220  ]>;
221// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: expected operand 1 of 'ExpectedMO' to be a MachineOperand; got imm 0
222// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Failed to parse pattern: '(ExpectedMO ?:$dst, (i32 0))'
223def expected_mo : GICombineRule<
224  (defs root:$dst),
225  (match (ExpectedMO $dst, (i32 0))),
226  (apply (COPY $dst, (i32 0)))>;
227// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: expected operand 1 of 'ExpectedMO' to be a MachineOperand; got imm 0:$z
228// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Failed to parse pattern: '(ExpectedMO ?:$dst, (i32 0):$z)'
229def expected_mo_namedimm : GICombineRule<
230  (defs root:$dst),
231  (match (ExpectedMO $dst, (i32 0):$z)),
232  (apply (COPY $dst, (i32 0)))>;
233
234// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: 'dum': using GICombinePatFrag is not supported in apply patterns
235def patfrag_in_apply : GICombineRule<
236  (defs root:$dst),
237  (match (COPY $dst, (i32 0))),
238  (apply (DummyPF):$dum)>;
239
240// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: cannot use 'DummyPF as match root
241def patfrag_cannot_be_root : GICombineRule<
242  (defs root:$root),
243  (match (DummyPF):$root),
244  (apply (COPY $dst, (i32 0)):$root)>;
245
246def TypedParams: GICombinePatFrag<
247  (outs root:$k),
248  (ins gi_mo:$i),
249  [
250    (pattern (G_ZEXT $k, i32:$i)),
251  ]>;
252// CHECK: :[[@LINE+3]]:{{[0-9]+}}: warning: impossible type constraints: operand 1 of 'broken' has type 'i64', but 'TypedParams' constrains it to 'i32'
253// CHECK: :[[@LINE+2]]:{{[0-9]+}}: note: operand 1 of 'broken' is 'k'
254// CHECK: :[[@LINE+1]]:{{[0-9]+}}: note: argument 1 of 'TypedParams' is 'i'
255def inconsistent_arg_type : GICombineRule<
256  (defs root:$dst),
257  (match (TypedParams $dst, i64:$k):$broken),
258  (apply (COPY $dst, (i32 0)))>;
259
260// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: all instructions that define root 'foo' in 'RootDefHasMultiDefs' can only have a single output operand
261// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Could not parse GICombinePatFrag 'RootDefHasMultiDefs'
262def RootDefHasMultiDefs: GICombinePatFrag<
263    (outs root:$foo),
264    (ins gi_imm:$cst),
265    [
266      (pattern (G_UNMERGE_VALUES $foo, $z, $y))
267    ]>;
268// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Failed to parse pattern: '(RootDefHasMultiDefs ?:$root, (i32 10))'
269def root_def_has_multi_defs : GICombineRule<
270  (defs root:$root),
271  (match (RootDefHasMultiDefs $root, (i32 10))),
272  (apply (COPY $root, (i32 0)))>;
273
274// CHECK: :[[@LINE+2]]:{{[0-9]+}}: error: matching/writing MIFlags is only allowed on CodeGenInstruction patterns
275// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Failed to parse pattern: '(DummyCXXPF ?:$x, (MIFlags FmArcp))'
276def miflags_in_pf : GICombineRule<
277  (defs root:$x),
278  (match (COPY $x, $y), (DummyCXXPF $x, (MIFlags FmArcp))),
279  (apply (COPY $x, $y))>;
280
281// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: '$pf' does not refer to a CodeGenInstruction in MIFlags of '__badtype_for_flagref_in_apply_apply_0'
282def badtype_for_flagref_in_apply : GICombineRule<
283  (defs root:$dst),
284  (match (G_ZEXT $dst, $src), (DummyCXXPF $src):$pf),
285  (apply (G_MUL $dst, $src, $src, (MIFlags $pf)))>;
286
287// CHECK: error: Failed to parse one or more rules
288
289def MyCombiner: GICombiner<"GenMyCombiner", [
290  too_many_perms,
291  undef_livein,
292  out_must_be_root,
293  bad_out_type,
294  unreachable_pat,
295  wip_match_opcode_patfrag,
296  nest_pat_frag,
297  dup_params_in,
298  dup_params_out,
299  dup_params_inout,
300  def_by_all_alts,
301  multi_def_in_pat,
302  expected_imm,
303  expected_imm_namedimm,
304  expected_mo,
305  expected_mo_namedimm,
306  patfrag_in_apply,
307  patfrag_cannot_be_root,
308  inconsistent_arg_type,
309  root_def_has_multi_defs,
310  miflags_in_pf,
311  badtype_for_flagref_in_apply
312]>;
313