[llubi] Add UTC helper (#180603)
This patch adds a UTC helper `llvm/utils/update_llubi_test_checks.py` to generate check lines for the trace. Generalizer and multiple prefixes are not supported since they are meaningless for traces. I know it is a bit weird, but I don't have a better idea :( I found that `llvm/utils/update_test_body.py` also works. But it is annoying to duplicate the command twice.
This commit is contained in:
parent
7b56bc85ca
commit
36caa31621
@ -328,6 +328,9 @@ assertions:
|
||||
update_test_checks.py
|
||||
opt
|
||||
|
||||
update_llubi_test_checks.py
|
||||
llubi
|
||||
|
||||
Precommit workflow for tests
|
||||
----------------------------
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llubi_test_checks.py UTC_ARGS: --version 6
|
||||
; RUN: llubi --verbose < %s 2>&1 | FileCheck %s
|
||||
|
||||
define i32 @main(i32 %argc, ptr %argv) {
|
||||
@ -5,7 +6,7 @@ define i32 @main(i32 %argc, ptr %argv) {
|
||||
}
|
||||
|
||||
; CHECK: Entering function: main
|
||||
; CHECK: i32 %argc = i32 1
|
||||
; CHECK: ptr %argv = ptr 0x8 [argv]
|
||||
; CHECK: ret i32 0
|
||||
; CHECK: Exiting function: main
|
||||
; CHECK-NEXT: i32 %argc = i32 1
|
||||
; CHECK-NEXT: ptr %argv = ptr 0x8 [argv]
|
||||
; CHECK-NEXT: ret i32 0
|
||||
; CHECK-NEXT: Exiting function: main
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llubi_test_checks.py UTC_ARGS: --version 6
|
||||
; RUN: llubi --verbose < %s 2>&1 | FileCheck %s
|
||||
|
||||
define i32 @main() {
|
||||
@ -5,5 +6,5 @@ define i32 @main() {
|
||||
}
|
||||
|
||||
; CHECK: Entering function: main
|
||||
; CHECK: ret i32 0
|
||||
; CHECK: Exiting function: main
|
||||
; CHECK-NEXT: ret i32 0
|
||||
; CHECK-NEXT: Exiting function: main
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llubi_test_checks.py UTC_ARGS: --version 6
|
||||
; RUN: not llubi --verbose < %s 2>&1 | FileCheck %s
|
||||
|
||||
define i32 @main(i32 %argc, ptr %argv) {
|
||||
ret i32 poison
|
||||
}
|
||||
; CHECK: Entering function: main
|
||||
; CHECK: i32 %argc = i32 1
|
||||
; CHECK: ptr %argv = ptr 0x8 [argv]
|
||||
; CHECK: ret i32 poison
|
||||
; CHECK: Exiting function: main
|
||||
; CHECK: error: Execution of function 'main' resulted in poison return value.
|
||||
; CHECK-NEXT: i32 %argc = i32 1
|
||||
; CHECK-NEXT: ptr %argv = ptr 0x8 [argv]
|
||||
; CHECK-NEXT: ret i32 poison
|
||||
; CHECK-NEXT: Exiting function: main
|
||||
; CHECK-NEXT: error: Execution of function 'main' resulted in poison return value.
|
||||
|
||||
@ -2723,6 +2723,7 @@ def get_autogennote_suffix(parser, args):
|
||||
"tool_binary",
|
||||
"opt_binary",
|
||||
"llc_binary",
|
||||
"llubi_binary",
|
||||
"clang",
|
||||
"opt",
|
||||
"llvm_bin",
|
||||
|
||||
135
llvm/utils/update_llubi_test_checks.py
Executable file
135
llvm/utils/update_llubi_test_checks.py
Executable file
@ -0,0 +1,135 @@
|
||||
#!/usr/bin/env python3
|
||||
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
# See https://llvm.org/LICENSE.txt for license information.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
"""A test case update script.
|
||||
|
||||
This script is a utility to update LLVM 'llubi' based test cases with new
|
||||
FileCheck patterns.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
from sys import stderr
|
||||
from traceback import print_exc
|
||||
import argparse
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from UpdateTestChecks import common
|
||||
|
||||
|
||||
# Invoke the tool that is being tested.
|
||||
def invoke_tool(exe, cmd_args, ir, check_rc):
|
||||
with open(ir) as ir_file:
|
||||
substitutions = common.getSubstitutions(ir)
|
||||
stdout = subprocess.run(
|
||||
exe + " " + common.applySubstitutions(cmd_args, substitutions),
|
||||
shell=True,
|
||||
stdin=ir_file,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
check=check_rc,
|
||||
).stdout.decode()
|
||||
# Fix line endings to unix CR style.
|
||||
return stdout.replace("\r\n", "\n")
|
||||
|
||||
|
||||
def update_test(ti: common.TestInfo):
|
||||
if len(ti.run_lines) == 0:
|
||||
common.warn("No RUN lines found in test: " + ti.path)
|
||||
return
|
||||
if len(ti.run_lines) > 1:
|
||||
common.warn("Multiple RUN lines found in test: " + ti.path)
|
||||
common.warn("Only the first RUN line will be processed.")
|
||||
|
||||
l = ti.run_lines[0]
|
||||
if "|" not in l:
|
||||
common.warn("Skipping unparsable RUN line: " + l)
|
||||
return
|
||||
|
||||
commands = [cmd.strip() for cmd in l.split("|")]
|
||||
assert len(commands) == 2
|
||||
llubi_cmd = commands[-2]
|
||||
filecheck_cmd = commands[-1]
|
||||
args = llubi_cmd.split(" ")
|
||||
llubi_tool = args[0]
|
||||
check_rc = True
|
||||
if len(args) > 1 and args[0] == "not":
|
||||
llubi_tool = args[1]
|
||||
check_rc = False
|
||||
|
||||
common.verify_filecheck_prefixes(filecheck_cmd)
|
||||
|
||||
if llubi_tool != "llubi":
|
||||
common.warn("Skipping non-llubi RUN line: " + l)
|
||||
return
|
||||
|
||||
if not filecheck_cmd.startswith("FileCheck "):
|
||||
common.warn("Skipping non-FileChecked RUN line: " + l)
|
||||
return
|
||||
|
||||
llubi_args = llubi_cmd[llubi_cmd.index(llubi_tool) + len(llubi_tool) :].strip()
|
||||
llubi_args = llubi_args.replace("< %s", "").replace("%s", "").strip()
|
||||
prefixes = common.get_check_prefixes(filecheck_cmd)
|
||||
|
||||
common.debug("Extracted llubi cmd:", llubi_tool, llubi_args)
|
||||
common.debug("Extracted FileCheck prefixes:", str(prefixes))
|
||||
prefix_set = set([prefix for prefix in prefixes])
|
||||
|
||||
raw_tool_output = invoke_tool(
|
||||
ti.args.llubi_binary or llubi_tool,
|
||||
llubi_args,
|
||||
ti.path,
|
||||
check_rc=check_rc,
|
||||
)
|
||||
if ti.args.llubi_binary:
|
||||
raw_tool_output = raw_tool_output.replace(ti.args.llubi_binary, llubi_tool)
|
||||
|
||||
output_lines = []
|
||||
common.dump_input_lines(output_lines, ti, prefix_set, ";")
|
||||
tool_output_lines = raw_tool_output.splitlines()
|
||||
if len(tool_output_lines) == 0:
|
||||
common.warn("No output from llubi.")
|
||||
else:
|
||||
output_lines.append("; CHECK: " + tool_output_lines[0])
|
||||
output_lines.extend(["; CHECK-NEXT: " + line for line in tool_output_lines[1:]])
|
||||
|
||||
common.debug("Writing %d lines to %s..." % (len(output_lines), ti.path))
|
||||
with open(ti.path, "wb") as f:
|
||||
f.writelines(["{}\n".format(l).encode("utf-8") for l in output_lines])
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument(
|
||||
"--llubi-binary",
|
||||
default=None,
|
||||
help='The "llubi" binary to use to generate the test case',
|
||||
)
|
||||
parser.add_argument(
|
||||
"--tool",
|
||||
default=None,
|
||||
help="Treat the given tool name as an llubi-like tool for which check lines should be generated",
|
||||
)
|
||||
parser.add_argument("tests", nargs="+")
|
||||
initial_args = common.parse_commandline_args(parser)
|
||||
|
||||
script_name = os.path.basename(__file__)
|
||||
|
||||
returncode = 0
|
||||
for ti in common.itertests(
|
||||
initial_args.tests, parser, script_name="utils/" + script_name
|
||||
):
|
||||
try:
|
||||
update_test(ti)
|
||||
except Exception as e:
|
||||
stderr.write(f"Error: Failed to update test {ti.path}\n")
|
||||
print_exc()
|
||||
returncode = 1
|
||||
return returncode
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Loading…
x
Reference in New Issue
Block a user