blob: 86adf77714a11939cc71975722da305488f91704 [file] [log] [blame]
Fangrui Songe0b9a4a2019-11-26 10:40:52 -08001#!/usr/bin/env python3
Justin Bogner8fdac762017-10-18 02:20:31 +00002
3"""Updates FileCheck checks in MIR tests.
4
5This script is a utility to update MIR based tests with new FileCheck
6patterns.
7
8The checks added by this script will cover the entire body of each
9function it handles. Virtual registers used are given names via
10FileCheck patterns, so if you do want to check a subset of the body it
11should be straightforward to trim out the irrelevant parts. None of
Gaëtan Bossue29f77d2022-12-08 20:49:04 +010012the YAML metadata will be checked, other than function names, and fixedStack
13if the --print-fixed-stack option is used.
Justin Bogner8fdac762017-10-18 02:20:31 +000014
15If there are multiple llc commands in a test, the full set of checks
16will be repeated for each different check pattern. Checks for patterns
17that are common between different commands will be left as-is by
18default, or removed if the --remove-common-prefixes flag is provided.
19"""
20
21from __future__ import print_function
22
23import argparse
24import collections
Simon Pilgrim2fa18632019-03-05 10:44:37 +000025import glob
Justin Bogner8fdac762017-10-18 02:20:31 +000026import os
27import re
28import subprocess
29import sys
30
Justin Bogner2589a0b2018-02-28 00:56:24 +000031from UpdateTestChecks import common
Justin Bogner8fdac762017-10-18 02:20:31 +000032
Tobias Hieta3c762872023-05-15 11:02:42 +020033MIR_FUNC_NAME_RE = re.compile(r" *name: *(?P<func>[A-Za-z0-9_.-]+)")
34MIR_BODY_BEGIN_RE = re.compile(r" *body: *\|")
35MIR_BASIC_BLOCK_RE = re.compile(r" *bb\.[0-9]+.*:$")
Jay Foad92b54b82023-09-18 12:14:46 +010036VREG_RE = re.compile(r"(%[0-9]+)(?:\.[a-z0-9_]+)?(?::[a-z0-9_]+)?(?:\([<>a-z0-9 ]+\))?")
Tobias Hieta3c762872023-05-15 11:02:42 +020037MI_FLAGS_STR = (
38 r"(frame-setup |frame-destroy |nnan |ninf |nsz |arcp |contract |afn "
39 r"|reassoc |nuw |nsw |exact |nofpexcept |nomerge )*"
40)
Jay Foad92b54b82023-09-18 12:14:46 +010041VREG_DEF_FLAGS_STR = r"(?:dead |undef )*"
Justin Bogner8fdac762017-10-18 02:20:31 +000042VREG_DEF_RE = re.compile(
Tobias Hieta3c762872023-05-15 11:02:42 +020043 r"^ *(?P<vregs>{2}{0}(?:, {2}{0})*) = "
44 r"{1}(?P<opcode>[A-Zt][A-Za-z0-9_]+)".format(
45 VREG_RE.pattern, MI_FLAGS_STR, VREG_DEF_FLAGS_STR
46 )
47)
48MIR_PREFIX_DATA_RE = re.compile(r"^ *(;|bb.[0-9].*: *$|[a-z]+:( |$)|$)")
Justin Bogner8fdac762017-10-18 02:20:31 +000049
Justin Bogner3a7928a2017-12-19 00:49:04 +000050IR_FUNC_NAME_RE = re.compile(
Tobias Hieta3c762872023-05-15 11:02:42 +020051 r"^\s*define\s+(?:internal\s+)?[^@]*@(?P<func>[A-Za-z0-9_.]+)\s*\("
52)
53IR_PREFIX_DATA_RE = re.compile(r"^ *(;|$)")
Justin Bogner3a7928a2017-12-19 00:49:04 +000054
Justin Bogner8fdac762017-10-18 02:20:31 +000055MIR_FUNC_RE = re.compile(
Tobias Hieta3c762872023-05-15 11:02:42 +020056 r"^---$"
57 r"\n"
58 r"^ *name: *(?P<func>[A-Za-z0-9_.-]+)$"
59 r".*?"
Jay Foad0f3446c2023-06-14 11:44:41 +010060 r"(?:^ *fixedStack: *(\[\])? *\n"
Tobias Hieta3c762872023-05-15 11:02:42 +020061 r"(?P<fixedStack>.*?)\n?"
62 r"^ *stack:"
Jay Foad0f3446c2023-06-14 11:44:41 +010063 r".*?)?"
Tobias Hieta3c762872023-05-15 11:02:42 +020064 r"^ *body: *\|\n"
65 r"(?P<body>.*?)\n"
66 r"^\.\.\.$",
67 flags=(re.M | re.S),
68)
Justin Bogner8fdac762017-10-18 02:20:31 +000069
Justin Bogner2589a0b2018-02-28 00:56:24 +000070
Justin Bogner8fdac762017-10-18 02:20:31 +000071class LLC:
72 def __init__(self, bin):
73 self.bin = bin
74
75 def __call__(self, args, ir):
Tobias Hieta3c762872023-05-15 11:02:42 +020076 if ir.endswith(".mir"):
77 args = "{} -x mir".format(args)
Justin Bogner8fdac762017-10-18 02:20:31 +000078 with open(ir) as ir_file:
Tobias Hieta3c762872023-05-15 11:02:42 +020079 stdout = subprocess.check_output(
80 "{} {}".format(self.bin, args), shell=True, stdin=ir_file
81 )
Simon Pilgrimff4c7c22019-03-02 11:14:01 +000082 if sys.version_info[0] > 2:
Tobias Hieta3c762872023-05-15 11:02:42 +020083 stdout = stdout.decode()
Justin Bogner8fdac762017-10-18 02:20:31 +000084 # Fix line endings to unix CR style.
Tobias Hieta3c762872023-05-15 11:02:42 +020085 stdout = stdout.replace("\r\n", "\n")
Justin Bogner8fdac762017-10-18 02:20:31 +000086 return stdout
87
88
89class Run:
90 def __init__(self, prefixes, cmd_args, triple):
91 self.prefixes = prefixes
92 self.cmd_args = cmd_args
93 self.triple = triple
94
95 def __getitem__(self, index):
96 return [self.prefixes, self.cmd_args, self.triple][index]
97
98
99def log(msg, verbose=True):
100 if verbose:
101 print(msg, file=sys.stderr)
102
103
Justin Bogner8fdac762017-10-18 02:20:31 +0000104def find_triple_in_ir(lines, verbose=False):
105 for l in lines:
Justin Bogner2589a0b2018-02-28 00:56:24 +0000106 m = common.TRIPLE_IR_RE.match(l)
Justin Bogner8fdac762017-10-18 02:20:31 +0000107 if m:
108 return m.group(1)
109 return None
110
111
Justin Bogner8fdac762017-10-18 02:20:31 +0000112def build_run_list(test, run_lines, verbose=False):
113 run_list = []
114 all_prefixes = []
115 for l in run_lines:
Tobias Hieta3c762872023-05-15 11:02:42 +0200116 if "|" not in l:
117 common.warn("Skipping unparsable RUN line: " + l)
David Bolvansky25721602019-08-07 14:44:50 +0000118 continue
119
Tobias Hieta3c762872023-05-15 11:02:42 +0200120 commands = [cmd.strip() for cmd in l.split("|", 1)]
Justin Bogner8fdac762017-10-18 02:20:31 +0000121 llc_cmd = commands[0]
Tobias Hieta3c762872023-05-15 11:02:42 +0200122 filecheck_cmd = commands[1] if len(commands) > 1 else ""
David Bolvanskybeca1b62019-07-29 17:41:00 +0000123 common.verify_filecheck_prefixes(filecheck_cmd)
Justin Bogner8fdac762017-10-18 02:20:31 +0000124
Tobias Hieta3c762872023-05-15 11:02:42 +0200125 if not llc_cmd.startswith("llc "):
126 common.warn("Skipping non-llc RUN line: {}".format(l), test_file=test)
Justin Bogner8fdac762017-10-18 02:20:31 +0000127 continue
Tobias Hieta3c762872023-05-15 11:02:42 +0200128 if not filecheck_cmd.startswith("FileCheck "):
129 common.warn(
130 "Skipping non-FileChecked RUN line: {}".format(l), test_file=test
131 )
Justin Bogner8fdac762017-10-18 02:20:31 +0000132 continue
133
134 triple = None
Justin Bogner2589a0b2018-02-28 00:56:24 +0000135 m = common.TRIPLE_ARG_RE.search(llc_cmd)
Justin Bogner8fdac762017-10-18 02:20:31 +0000136 if m:
137 triple = m.group(1)
138 # If we find -march but not -mtriple, use that.
Justin Bogner2589a0b2018-02-28 00:56:24 +0000139 m = common.MARCH_ARG_RE.search(llc_cmd)
Justin Bogner8fdac762017-10-18 02:20:31 +0000140 if m and not triple:
Tobias Hieta3c762872023-05-15 11:02:42 +0200141 triple = "{}--".format(m.group(1))
Justin Bogner8fdac762017-10-18 02:20:31 +0000142
Tobias Hieta3c762872023-05-15 11:02:42 +0200143 cmd_args = llc_cmd[len("llc") :].strip()
144 cmd_args = cmd_args.replace("< %s", "").replace("%s", "").strip()
Shengchen Kane1af2a22023-02-04 09:35:32 +0800145 check_prefixes = common.get_check_prefixes(filecheck_cmd)
Justin Bogner8fdac762017-10-18 02:20:31 +0000146 all_prefixes += check_prefixes
147
148 run_list.append(Run(check_prefixes, cmd_args, triple))
149
Nicolai Hähnle333bccf2022-05-25 01:57:14 +0200150 # Sort prefixes that are shared between run lines before unshared prefixes.
151 # This causes us to prefer printing shared prefixes.
Justin Bogner8fdac762017-10-18 02:20:31 +0000152 for run in run_list:
Nicolai Hähnle333bccf2022-05-25 01:57:14 +0200153 run.prefixes.sort(key=lambda prefix: -all_prefixes.count(prefix))
Justin Bogner8fdac762017-10-18 02:20:31 +0000154
Nicolai Hähnle333bccf2022-05-25 01:57:14 +0200155 return run_list
Justin Bogner8fdac762017-10-18 02:20:31 +0000156
157
158def find_functions_with_one_bb(lines, verbose=False):
159 result = []
160 cur_func = None
161 bbs = 0
162 for line in lines:
Justin Bognere1fa9ae3f2017-12-18 23:31:55 +0000163 m = MIR_FUNC_NAME_RE.match(line)
Justin Bogner8fdac762017-10-18 02:20:31 +0000164 if m:
165 if bbs == 1:
166 result.append(cur_func)
Tobias Hieta3c762872023-05-15 11:02:42 +0200167 cur_func = m.group("func")
Justin Bogner8fdac762017-10-18 02:20:31 +0000168 bbs = 0
Justin Bognere1fa9ae3f2017-12-18 23:31:55 +0000169 m = MIR_BASIC_BLOCK_RE.match(line)
Justin Bogner8fdac762017-10-18 02:20:31 +0000170 if m:
171 bbs += 1
172 if bbs == 1:
173 result.append(cur_func)
174 return result
175
176
Gaëtan Bossue29f77d2022-12-08 20:49:04 +0100177class FunctionInfo:
178 def __init__(self, body, fixedStack):
179 self.body = body
180 self.fixedStack = fixedStack
181
182 def __eq__(self, other):
183 if not isinstance(other, FunctionInfo):
184 return False
185 return self.body == other.body and self.fixedStack == other.fixedStack
186
187
Tobias Hieta3c762872023-05-15 11:02:42 +0200188def build_function_info_dictionary(
189 test, raw_tool_output, triple, prefixes, func_dict, verbose
190):
Justin Bogner8fdac762017-10-18 02:20:31 +0000191 for m in MIR_FUNC_RE.finditer(raw_tool_output):
Tobias Hieta3c762872023-05-15 11:02:42 +0200192 func = m.group("func")
193 fixedStack = m.group("fixedStack")
194 body = m.group("body")
Justin Bogner8fdac762017-10-18 02:20:31 +0000195 if verbose:
Tobias Hieta3c762872023-05-15 11:02:42 +0200196 log("Processing function: {}".format(func))
Justin Bogner8fdac762017-10-18 02:20:31 +0000197 for l in body.splitlines():
Tobias Hieta3c762872023-05-15 11:02:42 +0200198 log(" {}".format(l))
Nicolai Hähnle333bccf2022-05-25 01:57:14 +0200199
200 # Vreg mangling
201 mangled = []
202 vreg_map = {}
203 for func_line in body.splitlines(keepends=True):
204 m = VREG_DEF_RE.match(func_line)
205 if m:
Tobias Hieta3c762872023-05-15 11:02:42 +0200206 for vreg in VREG_RE.finditer(m.group("vregs")):
Jay Foadeebfa2f2023-09-15 13:10:45 +0100207 if vreg.group(1) in vreg_map:
208 name = vreg_map[vreg.group(1)]
209 else:
210 name = mangle_vreg(m.group("opcode"), vreg_map.values())
211 vreg_map[vreg.group(1)] = name
Nicolai Hähnle333bccf2022-05-25 01:57:14 +0200212 func_line = func_line.replace(
Tobias Hieta3c762872023-05-15 11:02:42 +0200213 vreg.group(1), "[[{}:%[0-9]+]]".format(name), 1
214 )
Nicolai Hähnle333bccf2022-05-25 01:57:14 +0200215 for number, name in vreg_map.items():
Tobias Hieta3c762872023-05-15 11:02:42 +0200216 func_line = re.sub(
217 r"{}\b".format(number), "[[{}]]".format(name), func_line
218 )
Nicolai Hähnle333bccf2022-05-25 01:57:14 +0200219 mangled.append(func_line)
Tobias Hieta3c762872023-05-15 11:02:42 +0200220 body = "".join(mangled)
Nicolai Hähnle333bccf2022-05-25 01:57:14 +0200221
Justin Bogner8fdac762017-10-18 02:20:31 +0000222 for prefix in prefixes:
Gaëtan Bossue29f77d2022-12-08 20:49:04 +0100223 info = FunctionInfo(body, fixedStack)
Nicolai Hähnle333bccf2022-05-25 01:57:14 +0200224 if func in func_dict[prefix]:
Gaëtan Bossue29f77d2022-12-08 20:49:04 +0100225 if func_dict[prefix][func] != info:
Nicolai Hähnle333bccf2022-05-25 01:57:14 +0200226 func_dict[prefix][func] = None
227 else:
Gaëtan Bossue29f77d2022-12-08 20:49:04 +0100228 func_dict[prefix][func] = info
Justin Bogner8fdac762017-10-18 02:20:31 +0000229
230
Tobias Hieta3c762872023-05-15 11:02:42 +0200231def add_checks_for_function(
232 test, output_lines, run_list, func_dict, func_name, single_bb, args
233):
Justin Bogner8fdac762017-10-18 02:20:31 +0000234 printed_prefixes = set()
235 for run in run_list:
236 for prefix in run.prefixes:
237 if prefix in printed_prefixes:
Nicolai Hähnle333bccf2022-05-25 01:57:14 +0200238 break
Justin Bogner8fdac762017-10-18 02:20:31 +0000239 if not func_dict[prefix][func_name]:
240 continue
Eddie Phillipse7ed55a2023-07-06 11:48:56 +0100241 if printed_prefixes:
242 # Add some space between different check prefixes.
243 indent = len(output_lines[-1]) - len(output_lines[-1].lstrip(" "))
244 output_lines.append(" "*indent + ";")
Justin Bogner8fdac762017-10-18 02:20:31 +0000245 printed_prefixes.add(prefix)
Tobias Hieta3c762872023-05-15 11:02:42 +0200246 log("Adding {} lines for {}".format(prefix, func_name), args.verbose)
247 add_check_lines(
248 test,
249 output_lines,
250 prefix,
251 func_name,
252 single_bb,
253 func_dict[prefix][func_name],
254 args,
255 )
Justin Bogner8fdac762017-10-18 02:20:31 +0000256 break
Nicolai Hähnle333bccf2022-05-25 01:57:14 +0200257 else:
258 common.warn(
Tobias Hieta3c762872023-05-15 11:02:42 +0200259 "Found conflicting asm for function: {}".format(func_name),
260 test_file=test,
261 )
Justin Bogner8fdac762017-10-18 02:20:31 +0000262 return output_lines
263
264
Tobias Hieta3c762872023-05-15 11:02:42 +0200265def add_check_lines(
266 test, output_lines, prefix, func_name, single_bb, func_info: FunctionInfo, args
267):
Gaëtan Bossue29f77d2022-12-08 20:49:04 +0100268 func_body = func_info.body.splitlines()
Justin Bogner8fdac762017-10-18 02:20:31 +0000269 if single_bb:
270 # Don't bother checking the basic block label for a single BB
271 func_body.pop(0)
272
273 if not func_body:
Tobias Hieta3c762872023-05-15 11:02:42 +0200274 common.warn(
275 "Function has no instructions to check: {}".format(func_name),
276 test_file=test,
277 )
Justin Bogner8fdac762017-10-18 02:20:31 +0000278 return
279
280 first_line = func_body[0]
Tobias Hieta3c762872023-05-15 11:02:42 +0200281 indent = len(first_line) - len(first_line.lstrip(" "))
Justin Bogner8fdac762017-10-18 02:20:31 +0000282 # A check comment, indented the appropriate amount
Tobias Hieta3c762872023-05-15 11:02:42 +0200283 check = "{:>{}}; {}".format("", indent, prefix)
Justin Bogner8fdac762017-10-18 02:20:31 +0000284
Tobias Hieta3c762872023-05-15 11:02:42 +0200285 output_lines.append("{}-LABEL: name: {}".format(check, func_name))
Justin Bogner8fdac762017-10-18 02:20:31 +0000286
Gaëtan Bossue29f77d2022-12-08 20:49:04 +0100287 if args.print_fixed_stack:
Tobias Hieta3c762872023-05-15 11:02:42 +0200288 output_lines.append("{}: fixedStack:".format(check))
Gaëtan Bossue29f77d2022-12-08 20:49:04 +0100289 for stack_line in func_info.fixedStack.splitlines():
Tobias Hieta3c762872023-05-15 11:02:42 +0200290 filecheck_directive = check + "-NEXT"
291 output_lines.append("{}: {}".format(filecheck_directive, stack_line))
Gaëtan Bossue29f77d2022-12-08 20:49:04 +0100292
293 first_check = True
Justin Bogner8fdac762017-10-18 02:20:31 +0000294 for func_line in func_body:
295 if not func_line.strip():
Alex Richardson19b7f392021-09-20 12:33:33 +0100296 # The mir printer prints leading whitespace so we can't use CHECK-EMPTY:
Tobias Hieta3c762872023-05-15 11:02:42 +0200297 output_lines.append(check + "-NEXT: {{" + func_line + "$}}")
Justin Bogner8fdac762017-10-18 02:20:31 +0000298 continue
Tobias Hieta3c762872023-05-15 11:02:42 +0200299 filecheck_directive = check if first_check else check + "-NEXT"
Alex Richardson19b7f392021-09-20 12:33:33 +0100300 first_check = False
Tobias Hieta3c762872023-05-15 11:02:42 +0200301 check_line = "{}: {}".format(filecheck_directive, func_line[indent:]).rstrip()
Justin Bogner8fdac762017-10-18 02:20:31 +0000302 output_lines.append(check_line)
303
304
305def mangle_vreg(opcode, current_names):
306 base = opcode
307 # Simplify some common prefixes and suffixes
Tobias Hieta3c762872023-05-15 11:02:42 +0200308 if opcode.startswith("G_"):
309 base = base[len("G_") :]
310 if opcode.endswith("_PSEUDO"):
311 base = base[: len("_PSEUDO")]
Justin Bogner8fdac762017-10-18 02:20:31 +0000312 # Shorten some common opcodes with long-ish names
Tobias Hieta3c762872023-05-15 11:02:42 +0200313 base = dict(
314 IMPLICIT_DEF="DEF",
315 GLOBAL_VALUE="GV",
316 CONSTANT="C",
317 FCONSTANT="C",
318 MERGE_VALUES="MV",
319 UNMERGE_VALUES="UV",
320 INTRINSIC="INT",
321 INTRINSIC_W_SIDE_EFFECTS="INT",
322 INSERT_VECTOR_ELT="IVEC",
323 EXTRACT_VECTOR_ELT="EVEC",
324 SHUFFLE_VECTOR="SHUF",
325 ).get(base, base)
Justin Bognera2178472017-10-18 15:37:09 +0000326 # Avoid ambiguity when opcodes end in numbers
Tobias Hieta3c762872023-05-15 11:02:42 +0200327 if len(base.rstrip("0123456789")) < len(base):
328 base += "_"
Justin Bogner8fdac762017-10-18 02:20:31 +0000329
330 i = 0
331 for name in current_names:
Tobias Hieta3c762872023-05-15 11:02:42 +0200332 if name.rstrip("0123456789") == base:
Justin Bogner8fdac762017-10-18 02:20:31 +0000333 i += 1
334 if i:
Tobias Hieta3c762872023-05-15 11:02:42 +0200335 return "{}{}".format(base, i)
Justin Bogner8fdac762017-10-18 02:20:31 +0000336 return base
337
338
339def should_add_line_to_output(input_line, prefix_set):
Eddie Phillipse7ed55a2023-07-06 11:48:56 +0100340 # Skip any check lines that we're handling as well as comments
Justin Bogner2589a0b2018-02-28 00:56:24 +0000341 m = common.CHECK_RE.match(input_line)
Eddie Phillipse7ed55a2023-07-06 11:48:56 +0100342 if (m and m.group(1) in prefix_set) or re.search("^[ \t]*;", input_line):
Justin Bogner8fdac762017-10-18 02:20:31 +0000343 return False
344 return True
345
346
Gaëtan Bossuc7f0bc32022-12-08 21:50:02 +0100347def update_test_file(args, test, autogenerated_note):
Justin Bogner8fdac762017-10-18 02:20:31 +0000348 with open(test) as fd:
349 input_lines = [l.rstrip() for l in fd]
350
David Bolvansky25721602019-08-07 14:44:50 +0000351 triple_in_ir = find_triple_in_ir(input_lines, args.verbose)
Alex Richardson8a057a42019-12-02 10:50:23 +0000352 run_lines = common.find_run_lines(test, input_lines)
Nicolai Hähnle333bccf2022-05-25 01:57:14 +0200353 run_list = build_run_list(test, run_lines, args.verbose)
David Bolvansky25721602019-08-07 14:44:50 +0000354
355 simple_functions = find_functions_with_one_bb(input_lines, args.verbose)
Justin Bogner8fdac762017-10-18 02:20:31 +0000356
357 func_dict = {}
358 for run in run_list:
359 for prefix in run.prefixes:
360 func_dict.update({prefix: dict()})
361 for prefixes, llc_args, triple_in_cmd in run_list:
Tobias Hieta3c762872023-05-15 11:02:42 +0200362 log("Extracted LLC cmd: llc {}".format(llc_args), args.verbose)
363 log("Extracted FileCheck prefixes: {}".format(prefixes), args.verbose)
Justin Bogner8fdac762017-10-18 02:20:31 +0000364
Gaëtan Bossuc7f0bc32022-12-08 21:50:02 +0100365 raw_tool_output = args.llc_binary(llc_args, test)
Justin Bogner8fdac762017-10-18 02:20:31 +0000366 if not triple_in_cmd and not triple_in_ir:
Tobias Hieta3c762872023-05-15 11:02:42 +0200367 common.warn("No triple found: skipping file", test_file=test)
Justin Bogner8fdac762017-10-18 02:20:31 +0000368 return
369
Tobias Hieta3c762872023-05-15 11:02:42 +0200370 build_function_info_dictionary(
371 test,
372 raw_tool_output,
373 triple_in_cmd or triple_in_ir,
374 prefixes,
375 func_dict,
376 args.verbose,
377 )
Justin Bogner8fdac762017-10-18 02:20:31 +0000378
Tobias Hieta3c762872023-05-15 11:02:42 +0200379 state = "toplevel"
Justin Bogner8fdac762017-10-18 02:20:31 +0000380 func_name = None
381 prefix_set = set([prefix for run in run_list for prefix in run.prefixes])
Tobias Hieta3c762872023-05-15 11:02:42 +0200382 log("Rewriting FileCheck prefixes: {}".format(prefix_set), args.verbose)
Justin Bogner8fdac762017-10-18 02:20:31 +0000383
Justin Bogner8fdac762017-10-18 02:20:31 +0000384 output_lines = []
385 output_lines.append(autogenerated_note)
386
387 for input_line in input_lines:
388 if input_line == autogenerated_note:
389 continue
390
Tobias Hieta3c762872023-05-15 11:02:42 +0200391 if state == "toplevel":
Justin Bogner3a7928a2017-12-19 00:49:04 +0000392 m = IR_FUNC_NAME_RE.match(input_line)
393 if m:
Tobias Hieta3c762872023-05-15 11:02:42 +0200394 state = "ir function prefix"
395 func_name = m.group("func")
396 if input_line.rstrip("| \r\n") == "---":
397 state = "document"
Justin Bogner8fdac762017-10-18 02:20:31 +0000398 output_lines.append(input_line)
Tobias Hieta3c762872023-05-15 11:02:42 +0200399 elif state == "document":
Justin Bognere1fa9ae3f2017-12-18 23:31:55 +0000400 m = MIR_FUNC_NAME_RE.match(input_line)
Justin Bogner8fdac762017-10-18 02:20:31 +0000401 if m:
Tobias Hieta3c762872023-05-15 11:02:42 +0200402 state = "mir function metadata"
403 func_name = m.group("func")
404 if input_line.strip() == "...":
405 state = "toplevel"
Justin Bogner8fdac762017-10-18 02:20:31 +0000406 func_name = None
407 if should_add_line_to_output(input_line, prefix_set):
408 output_lines.append(input_line)
Tobias Hieta3c762872023-05-15 11:02:42 +0200409 elif state == "mir function metadata":
Justin Bogner8fdac762017-10-18 02:20:31 +0000410 if should_add_line_to_output(input_line, prefix_set):
411 output_lines.append(input_line)
Justin Bognere1fa9ae3f2017-12-18 23:31:55 +0000412 m = MIR_BODY_BEGIN_RE.match(input_line)
Justin Bogner8fdac762017-10-18 02:20:31 +0000413 if m:
414 if func_name in simple_functions:
415 # If there's only one block, put the checks inside it
Tobias Hieta3c762872023-05-15 11:02:42 +0200416 state = "mir function prefix"
Justin Bogner8fdac762017-10-18 02:20:31 +0000417 continue
Tobias Hieta3c762872023-05-15 11:02:42 +0200418 state = "mir function body"
419 add_checks_for_function(
420 test,
421 output_lines,
422 run_list,
423 func_dict,
424 func_name,
425 single_bb=False,
426 args=args,
427 )
428 elif state == "mir function prefix":
Justin Bognere1fa9ae3f2017-12-18 23:31:55 +0000429 m = MIR_PREFIX_DATA_RE.match(input_line)
Justin Bogner8fdac762017-10-18 02:20:31 +0000430 if not m:
Tobias Hieta3c762872023-05-15 11:02:42 +0200431 state = "mir function body"
432 add_checks_for_function(
433 test,
434 output_lines,
435 run_list,
436 func_dict,
437 func_name,
438 single_bb=True,
439 args=args,
440 )
Justin Bogner8fdac762017-10-18 02:20:31 +0000441
442 if should_add_line_to_output(input_line, prefix_set):
443 output_lines.append(input_line)
Tobias Hieta3c762872023-05-15 11:02:42 +0200444 elif state == "mir function body":
445 if input_line.strip() == "...":
446 state = "toplevel"
Justin Bogner8fdac762017-10-18 02:20:31 +0000447 func_name = None
448 if should_add_line_to_output(input_line, prefix_set):
449 output_lines.append(input_line)
Tobias Hieta3c762872023-05-15 11:02:42 +0200450 elif state == "ir function prefix":
Justin Bogner3a7928a2017-12-19 00:49:04 +0000451 m = IR_PREFIX_DATA_RE.match(input_line)
452 if not m:
Tobias Hieta3c762872023-05-15 11:02:42 +0200453 state = "ir function body"
454 add_checks_for_function(
455 test,
456 output_lines,
457 run_list,
458 func_dict,
459 func_name,
460 single_bb=False,
461 args=args,
462 )
Justin Bogner3a7928a2017-12-19 00:49:04 +0000463
464 if should_add_line_to_output(input_line, prefix_set):
465 output_lines.append(input_line)
Tobias Hieta3c762872023-05-15 11:02:42 +0200466 elif state == "ir function body":
467 if input_line.strip() == "}":
468 state = "toplevel"
Justin Bogner3a7928a2017-12-19 00:49:04 +0000469 func_name = None
470 if should_add_line_to_output(input_line, prefix_set):
471 output_lines.append(input_line)
472
Tobias Hieta3c762872023-05-15 11:02:42 +0200473 log("Writing {} lines to {}...".format(len(output_lines), test), args.verbose)
Justin Bogner8fdac762017-10-18 02:20:31 +0000474
Tobias Hieta3c762872023-05-15 11:02:42 +0200475 with open(test, "wb") as fd:
476 fd.writelines(["{}\n".format(l).encode("utf-8") for l in output_lines])
Justin Bogner8fdac762017-10-18 02:20:31 +0000477
478
479def main():
480 parser = argparse.ArgumentParser(
Tobias Hieta3c762872023-05-15 11:02:42 +0200481 description=__doc__, formatter_class=argparse.RawTextHelpFormatter
482 )
483 parser.add_argument(
484 "--llc-binary",
485 default="llc",
486 type=LLC,
487 help='The "llc" binary to generate the test case with',
488 )
489 parser.add_argument(
490 "--print-fixed-stack",
491 action="store_true",
492 help="Add check lines for fixedStack",
493 )
494 parser.add_argument("tests", nargs="+")
Alex Richardson0d256972019-11-20 13:19:48 +0000495 args = common.parse_commandline_args(parser)
Justin Bogner8fdac762017-10-18 02:20:31 +0000496
Gaëtan Bossuc7f0bc32022-12-08 21:50:02 +0100497 script_name = os.path.basename(__file__)
Tobias Hieta3c762872023-05-15 11:02:42 +0200498 for ti in common.itertests(args.tests, parser, script_name="utils/" + script_name):
Justin Bognerb745be52017-10-18 22:36:08 +0000499 try:
Gaëtan Bossuc7f0bc32022-12-08 21:50:02 +0100500 update_test_file(ti.args, ti.path, ti.test_autogenerated_note)
Justin Bognerb745be52017-10-18 22:36:08 +0000501 except Exception:
Tobias Hieta3c762872023-05-15 11:02:42 +0200502 common.warn("Error processing file", test_file=ti.path)
Justin Bognerb745be52017-10-18 22:36:08 +0000503 raise
Justin Bogner8fdac762017-10-18 02:20:31 +0000504
505
Tobias Hieta3c762872023-05-15 11:02:42 +0200506if __name__ == "__main__":
507 main()