-
Notifications
You must be signed in to change notification settings - Fork 14.3k
update_test_checks: Fix preservation of meta variable names with --include-generated-funcs #86160
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
Conversation
@llvm/pr-subscribers-testing-tools Author: Jannik Silvanus (jasilvanus) ChangesWith This caused existing check lines to not be detected with This is fixed in this patch. Full diff: https://github.com/llvm/llvm-project/pull/86160.diff 4 Files Affected:
diff --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/stable_ir_values5.ll b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/stable_ir_values5.ll
new file mode 100644
index 00000000000000..a788c82872a07f
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/stable_ir_values5.ll
@@ -0,0 +1,22 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs --version 3
+; RUN: opt < %s -S | FileCheck %s
+
+; With --include-generated-funcs, check lines are separate from IR function bodies.
+; This needs to be handled separately by the UTC parser for existing check lines.
+; This test tests this case.
+
+define i32 @func({i32, i32} %x, i32 %y) {
+ %x.i34 = extractvalue {i32, i32} %x, 0
+ %1 = add i32 %y, 1
+ %2 = add i32 %x.i34, %1
+ %3 = mul i32 %2, 3
+ ret i32 %3
+}
+
+; CHECK-LABEL: define i32 @func(
+; CHECK-SAME: { i32, i32 } [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[X_I33:%.*]] = extractvalue { i32, i32 } [[X]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X_I33]], [[Y]]
+; CHECK-NEXT: [[TMP2:%.*]] = mul i32 [[TMP1]], 3
+; CHECK-NEXT: ret i32 [[TMP2]]
+;
diff --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/stable_ir_values5.ll.expected b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/stable_ir_values5.ll.expected
new file mode 100644
index 00000000000000..09df76d9dadc62
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/stable_ir_values5.ll.expected
@@ -0,0 +1,23 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs --version 3
+; RUN: opt < %s -S | FileCheck %s
+
+; With --include-generated-funcs, check lines are separate from IR function bodies.
+; This needs to be handled separately by the UTC parser for existing check lines.
+; This test tests this case.
+
+define i32 @func({i32, i32} %x, i32 %y) {
+ %x.i34 = extractvalue {i32, i32} %x, 0
+ %1 = add i32 %y, 1
+ %2 = add i32 %x.i34, %1
+ %3 = mul i32 %2, 3
+ ret i32 %3
+}
+
+; CHECK-LABEL: define i32 @func(
+; CHECK-SAME: { i32, i32 } [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[X_I33:%.*]] = extractvalue { i32, i32 } [[X]], 0
+; CHECK-NEXT: [[TMP3:%.*]] = add i32 [[Y]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X_I33]], [[TMP3]]
+; CHECK-NEXT: [[TMP2:%.*]] = mul i32 [[TMP1]], 3
+; CHECK-NEXT: ret i32 [[TMP2]]
+;
diff --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/stable_ir_values5.test b/llvm/test/tools/UpdateTestChecks/update_test_checks/stable_ir_values5.test
new file mode 100644
index 00000000000000..a04a9fa3e90785
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/stable_ir_values5.test
@@ -0,0 +1,2 @@
+# RUN: cp -f %S/Inputs/stable_ir_values5.ll %t.ll && %update_test_checks %t.ll
+# RUN: diff -u %t.ll %S/Inputs/stable_ir_values5.ll.expected
diff --git a/llvm/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py
index ecb19d233a8d1a..01ed6d5ce6e067 100644
--- a/llvm/utils/UpdateTestChecks/common.py
+++ b/llvm/utils/UpdateTestChecks/common.py
@@ -430,36 +430,81 @@ def collect_original_check_lines(ti: TestInfo, prefix_set: set):
result[func_name][prefix] is filled with a list of right-hand-sides of check
lines.
"""
- result = {}
+ # We need to detect check lines, and associate them with the correct functions and prefixes.
+ # There are two formats how IR and check lines are combined. In the standard format,
+ # they are interleaved, and it suffices to parse IR function definitions in order to keep
+ # track of the current function:
+ #
+ # define i32 @func1(i32 %x) {
+ # ; CHECK-LABEL: define i32 @func1(
+ # ; CHECK-NEXT: /* check lines */
+ # ;
+ # %1 = /* IR body of @func1 */
+ #
+ # define i32 @func2(i32 %x) {
+ # ; CHECK-LABEL: define i32 @func2(
+ # ; CHECK-NEXT: /* check lines */
+ # ;
+ # %1 = /* IR body of @func2 */
+ #
+ # However, with --include-generated-funcs, check lines are separate from IR function bodies,
+ # and we also need to parse CHECK lines of function definitions:
+ #
+ # define i32 @func1(i32 %x) {
+ # /* IR body */
+ #
+ # define i32 @func2(..) {
+ # /* IR body */
+ #
+ # ; CHECK-LABEL: define i32 @func1
+ # ; CHECK-NEXT /* check lines for func1 */
+ #
+ # ; CHECK-LABEL: define i32 @func2
+ # ; CHECK-NEXT /* check lines for func2 */
+
+ result = collections.defaultdict(dict)
current_function = None
+
+ def update_current_function(line):
+ m = IR_FUNCTION_RE.match(line)
+ if m is None:
+ return
+ func_name = m.group(1)
+ if ti.args.function is not None and func_name != ti.args.function:
+ # When filtering on a specific function, skip all others.
+ return
+
+ nonlocal current_function
+ current_function = result[func_name]
+
for input_line_info in ti.ro_iterlines():
input_line = input_line_info.line
- if current_function is not None:
- if input_line == "":
- continue
- if input_line.lstrip().startswith(";"):
- m = CHECK_RE.match(input_line)
- if (
- m is not None
- and m.group(1) in prefix_set
- and m.group(2) not in ["LABEL", "SAME"]
- ):
- if m.group(1) not in current_function:
- current_function[m.group(1)] = []
- current_function[m.group(1)].append(input_line[m.end() :].strip())
- continue
+ if input_line == "":
+ continue
+ m = None
+ if input_line.lstrip().startswith(";"):
+ m = CHECK_RE.match(input_line)
+ if m is not None and m.group(2) == "LABEL":
+ # Update current_function if the current line is a CHECK of a function definition
+ line_remainder = input_line[len(m.group(0)):]
+ update_current_function(line_remainder)
+ else:
current_function = None
- m = IR_FUNCTION_RE.match(input_line)
- if m is not None:
- func_name = m.group(1)
- if ti.args.function is not None and func_name != ti.args.function:
- # When filtering on a specific function, skip all others.
- continue
+ if current_function is not None:
+ if (
+ m is not None
+ and m.group(1) in prefix_set
+ and m.group(2) not in ["LABEL", "SAME"]
+ ):
+ if m.group(1) not in current_function:
+ current_function[m.group(1)] = []
+ current_function[m.group(1)].append(input_line[m.end() :].strip())
+ continue
- assert func_name not in result
- current_function = result[func_name] = {}
+ # Update current_function if the current line is an IR function definition
+ update_current_function(input_line)
return result
|
✅ With the latest revision this PR passed the Python code formatter. |
…clude-generated-funcs With --include-generated-funcs, check lines for function bodies are separate from the IR function bodies. This needs to be handled differently by the UTC parser for existing check lines. This caused existing check lines to not be detected with --include-generated-funcs, which in turn effectively disabled the mechanism to preserve variable meta names where possible. This is fixed in this patch.
450fc07
to
175b7bd
Compare
Closing in favour of #87988. |
With
--include-generated-funcs
, check lines for function bodies are separate fromthe IR function bodies. This needs to be handled differently by the UTC parser
for existing check lines.
This caused existing check lines to not be detected with
--include-generated-funcs
,which in turn effectively disabled the mechanism to preserve variable meta names
where possible.
This is fixed in this patch.