Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[GlobalISel] Add a update_givaluetracking_test_checks.py script #140296

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions 20 llvm/test/CodeGen/AArch64/GlobalISel/knownbits-const.mir
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -mtriple aarch64 -passes="print<gisel-value-tracking>" %s -o - 2>&1 | FileCheck %s
# NOTE: Assertions have been autogenerated by utils/update_givaluetracking_test_checks.py UTC_ARGS: --version 5
# RUN: llc -mtriple aarch64 -passes="print<gisel-value-tracking>" %s -filetype=null 2>&1 | FileCheck %s

---
name: Cst
tracksRegLiveness: true
body: |
bb.1:
; CHECK-LABEL: name: @Cst
; CHECK-NEXT: %0:_ KnownBits:00000001 SignBits:7
; CHECK-NEXT: %1:_ KnownBits:00000001 SignBits:7
; CHECK-LABEL: name: @Cst
; CHECK-NEXT: %0:_ KnownBits:00000001 SignBits:7
; CHECK-NEXT: %1:_ KnownBits:00000001 SignBits:7
%0:_(s8) = G_CONSTANT i8 1
%1:_(s8) = COPY %0
...
---
name: CstWithClass
# We can't analyze %0 due to the lack of an LLT. We will get a default
# constructed KnownBits back. %0 will have the correct size but we will
# not know any further info.
tracksRegLiveness: true
body: |
bb.1:
; CHECK-LABEL: name: @CstWithClass
; CHECK-NEXT: %1:_ KnownBits:???????????????????????????????? SignBits:1
; We can't analyze %0 due to the lack of an LLT. We will get a default
; constructed KnownBits back. %0 will have the correct size but we will
; not know any further info.
; CHECK-LABEL: name: @CstWithClass
; CHECK-NEXT: %1:_ KnownBits:???????????????????????????????? SignBits:1
%0:gpr32 = MOVi32imm 1
%1:_(s32) = COPY %0
...
1 change: 1 addition & 0 deletions 1 llvm/test/tools/UpdateTestChecks/lit.local.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ if os.path.isfile(llc_path):
llc_arg = "--llc-binary " + shell_quote(llc_path)
add_update_script_substitution("%update_llc_test_checks", extra_args=llc_arg)
add_update_script_substitution("%update_mir_test_checks", extra_args=llc_arg)
add_update_script_substitution("%update_givaluetracking_test_checks", extra_args=llc_arg)

opt_path = os.path.join(config.llvm_tools_dir, "opt")
if os.path.isfile(opt_path):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# NOTE: Assertions have been autogenerated by utils/update_givaluetracking_test_checks.py UTC_ARGS: --version 5
# RUN: llc -mtriple aarch64 -passes="print<gisel-value-tracking>" %s -filetype=null 2>&1 | FileCheck %s

---
name: Cst
body: |
bb.1:
%0:_(s8) = G_CONSTANT i8 1
%1:_(s8) = COPY %0
davemgreen marked this conversation as resolved.
Show resolved Hide resolved
...
---
name: Test2
body: |
bb.1:
; Note: This comment should not be removed, the check lines below should be updated
; CHECK-LABEL: name: @Test2
; CHECK-NEXT: %1:_ KnownBits:???????????????????????????????? SignBits:1
; CHECK-NEXT: %named:_ KnownBits:???????????????????????????????????????????????????????????????? SignBits:1
; CHECK-NEXT: %3:_ KnownBits:???????????????????????????????? SignBits:1
; CHECK-NEXT: %4:_ KnownBits:???????????????????????????????? SignBits:1
%0:gpr32 = COPY $w0
%1:_(s32) = COPY %0
davemgreen marked this conversation as resolved.
Show resolved Hide resolved
%named:_(s64) = G_ZEXT %1
%3:_(s32), %4:_(s32) = G_UNMERGE_VALUES %named(s64)
$w0 = COPY %3(s32)
$w1 = COPY %4(s32)
RET_ReallyLR
...
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# NOTE: Assertions have been autogenerated by utils/update_givaluetracking_test_checks.py UTC_ARGS: --version 5
# RUN: llc -mtriple aarch64 -passes="print<gisel-value-tracking>" %s -filetype=null 2>&1 | FileCheck %s

---
name: Cst
body: |
bb.1:
; CHECK-LABEL: name: @Cst
; CHECK-NEXT: %0:_ KnownBits:00000001 SignBits:7
; CHECK-NEXT: %1:_ KnownBits:00000001 SignBits:7
%0:_(s8) = G_CONSTANT i8 1
%1:_(s8) = COPY %0
...
---
name: Test2
body: |
bb.1:
; Note: This comment should not be removed, the check lines below should be updated
; CHECK-LABEL: name: @Test2
; CHECK-NEXT: %1:_ KnownBits:???????????????????????????????? SignBits:1
; CHECK-NEXT: %named:_ KnownBits:00000000000000000000000000000000???????????????????????????????? SignBits:32
; CHECK-NEXT: %3:_ KnownBits:???????????????????????????????? SignBits:1
; CHECK-NEXT: %4:_ KnownBits:00000000000000000000000000000000 SignBits:32
%0:gpr32 = COPY $w0
%1:_(s32) = COPY %0
%named:_(s64) = G_ZEXT %1
%3:_(s32), %4:_(s32) = G_UNMERGE_VALUES %named(s64)
$w0 = COPY %3(s32)
$w1 = COPY %4(s32)
RET_ReallyLR
...
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# REQUIRES: aarch64-registered-target
# RUN: cp -f %S/Inputs/const.mir %t.mir && %update_givaluetracking_test_checks %t.mir
# RUN: diff -u %S/Inputs/const.mir.expected %t.mir
# RUN: FileCheck %t.mir < %t.mir
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# These tests require llc.
if "llc-binary" not in config.available_features:
config.unsupported = True
238 changes: 238 additions & 0 deletions 238 llvm/utils/UpdateTestChecks/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -2270,6 +2270,244 @@ def add_analyze_checks(
)


IR_FUNC_NAME_RE = re.compile(
r"^\s*define\s+(?:internal\s+)?[^@]*@(?P<func>[A-Za-z0-9_.]+)\s*\("
)
IR_PREFIX_DATA_RE = re.compile(r"^ *(;|$)")
MIR_FUNC_NAME_RE = re.compile(r" *name: *(?P<func>[A-Za-z0-9_.-]+)")
MIR_BODY_BEGIN_RE = re.compile(r" *body: *\|")
MIR_BASIC_BLOCK_RE = re.compile(r" *bb\.[0-9]+.*:$")
MIR_PREFIX_DATA_RE = re.compile(r"^ *(;|bb.[0-9].*: *$|[a-z]+:( |$)|$)")


def find_mir_functions_with_one_bb(lines, verbose=False):
result = []
cur_func = None
bbs = 0
for line in lines:
m = MIR_FUNC_NAME_RE.match(line)
if m:
if bbs == 1:
result.append(cur_func)
cur_func = m.group("func")
bbs = 0
m = MIR_BASIC_BLOCK_RE.match(line)
if m:
bbs += 1
if bbs == 1:
result.append(cur_func)
return result


def add_mir_checks_for_function(
test,
output_lines,
run_list,
func_dict,
func_name,
single_bb,
print_fixed_stack,
first_check_is_next,
at_the_function_name,
):
printed_prefixes = set()
for run in run_list:
for prefix in run[0]:
if prefix in printed_prefixes:
break
if not func_dict[prefix][func_name]:
continue
if printed_prefixes:
# Add some space between different check prefixes.
indent = len(output_lines[-1]) - len(output_lines[-1].lstrip(" "))
output_lines.append(" " * indent + ";")
printed_prefixes.add(prefix)
add_mir_check_lines(
test,
output_lines,
prefix,
("@" if at_the_function_name else "") + func_name,
single_bb,
func_dict[prefix][func_name],
print_fixed_stack,
first_check_is_next,
)
break
else:
warn(
"Found conflicting asm for function: {}".format(func_name),
test_file=test,
)
return output_lines


def add_mir_check_lines(
test,
output_lines,
prefix,
func_name,
single_bb,
func_info,
print_fixed_stack,
first_check_is_next,
):
func_body = str(func_info).splitlines()
if single_bb:
# Don't bother checking the basic block label for a single BB
func_body.pop(0)

if not func_body:
warn(
"Function has no instructions to check: {}".format(func_name),
test_file=test,
)
return

first_line = func_body[0]
indent = len(first_line) - len(first_line.lstrip(" "))
# A check comment, indented the appropriate amount
check = "{:>{}}; {}".format("", indent, prefix)

output_lines.append("{}-LABEL: name: {}".format(check, func_name))

if print_fixed_stack:
output_lines.append("{}: fixedStack:".format(check))
for stack_line in func_info.extrascrub.splitlines():
filecheck_directive = check + "-NEXT"
output_lines.append("{}: {}".format(filecheck_directive, stack_line))

first_check = not first_check_is_next
for func_line in func_body:
if not func_line.strip():
# The mir printer prints leading whitespace so we can't use CHECK-EMPTY:
output_lines.append(check + "-NEXT: {{" + func_line + "$}}")
continue
filecheck_directive = check if first_check else check + "-NEXT"
first_check = False
check_line = "{}: {}".format(filecheck_directive, func_line[indent:]).rstrip()
output_lines.append(check_line)


def should_add_mir_line_to_output(input_line, prefix_set):
# Skip any check lines that we're handling as well as comments
m = CHECK_RE.match(input_line)
if (m and m.group(1) in prefix_set) or input_line.strip() == ";":
return False
return True


def add_mir_checks(
input_lines,
prefix_set,
autogenerated_note,
test,
run_list,
func_dict,
print_fixed_stack,
first_check_is_next,
at_the_function_name,
):
simple_functions = find_mir_functions_with_one_bb(input_lines)

output_lines = []
output_lines.append(autogenerated_note)

func_name = None
state = "toplevel"
for input_line in input_lines:
if input_line == autogenerated_note:
continue

if state == "toplevel":
m = IR_FUNC_NAME_RE.match(input_line)
if m:
state = "ir function prefix"
func_name = m.group("func")
if input_line.rstrip("| \r\n") == "---":
state = "document"
output_lines.append(input_line)
elif state == "document":
m = MIR_FUNC_NAME_RE.match(input_line)
if m:
state = "mir function metadata"
func_name = m.group("func")
if input_line.strip() == "...":
state = "toplevel"
func_name = None
if should_add_mir_line_to_output(input_line, prefix_set):
output_lines.append(input_line)
elif state == "mir function metadata":
if should_add_mir_line_to_output(input_line, prefix_set):
output_lines.append(input_line)
m = MIR_BODY_BEGIN_RE.match(input_line)
if m:
if func_name in simple_functions:
# If there's only one block, put the checks inside it
state = "mir function prefix"
continue
state = "mir function body"
add_mir_checks_for_function(
test,
output_lines,
run_list,
func_dict,
func_name,
single_bb=False,
print_fixed_stack=print_fixed_stack,
first_check_is_next=first_check_is_next,
at_the_function_name=at_the_function_name,
)
elif state == "mir function prefix":
m = MIR_PREFIX_DATA_RE.match(input_line)
if not m:
state = "mir function body"
add_mir_checks_for_function(
test,
output_lines,
run_list,
func_dict,
func_name,
single_bb=True,
print_fixed_stack=print_fixed_stack,
first_check_is_next=first_check_is_next,
at_the_function_name=at_the_function_name,
)

if should_add_mir_line_to_output(input_line, prefix_set):
output_lines.append(input_line)
elif state == "mir function body":
if input_line.strip() == "...":
state = "toplevel"
func_name = None
if should_add_mir_line_to_output(input_line, prefix_set):
output_lines.append(input_line)
elif state == "ir function prefix":
m = IR_PREFIX_DATA_RE.match(input_line)
if not m:
state = "ir function body"
add_mir_checks_for_function(
test,
output_lines,
run_list,
func_dict,
func_name,
single_bb=False,
print_fixed_stack=print_fixed_stack,
first_check_is_next=first_check_is_next,
at_the_function_name=at_the_function_name,
)

if should_add_mir_line_to_output(input_line, prefix_set):
output_lines.append(input_line)
elif state == "ir function body":
if input_line.strip() == "}":
state = "toplevel"
func_name = None
if should_add_mir_line_to_output(input_line, prefix_set):
output_lines.append(input_line)
return output_lines


def build_global_values_dictionary(glob_val_dict, raw_tool_output, prefixes, ginfo):
for nameless_value in ginfo.get_nameless_values():
if nameless_value.global_ir_rhs_regexp is None:
Expand Down
Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.