[llvm] update_test_checks: Fix preservation of meta variable names with --include-generated-funcs (PR #86160)

Jannik Silvanus via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 21 11:00:55 PDT 2024


https://github.com/jasilvanus updated https://github.com/llvm/llvm-project/pull/86160

>From 2ebd48734235ce0eed56eccffefa00ff3c4a9bdf Mon Sep 17 00:00:00 2001
From: Jannik Silvanus <jannik.silvanus at amd.com>
Date: Thu, 21 Mar 2024 18:47:45 +0100
Subject: [PATCH 1/2] update_test_checks: Precommit test for
 --include-generated-funcs

---
 .../Inputs/stable_ir_values5.ll               | 22 ++++++++++++++++++
 .../Inputs/stable_ir_values5.ll.expected      | 23 +++++++++++++++++++
 .../update_test_checks/stable_ir_values5.test |  2 ++
 3 files changed, 47 insertions(+)
 create mode 100644 llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/stable_ir_values5.ll
 create mode 100644 llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/stable_ir_values5.ll.expected
 create mode 100644 llvm/test/tools/UpdateTestChecks/update_test_checks/stable_ir_values5.test

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..50c883f55a4673
--- /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_I34:%.*]] = extractvalue { i32, i32 } [[X]], 0
+; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[Y]], 1
+; CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[X_I34]], [[TMP1]]
+; CHECK-NEXT:    [[TMP3:%.*]] = mul i32 [[TMP2]], 3
+; CHECK-NEXT:    ret i32 [[TMP3]]
+;
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

>From 175b7bde824e123e3087521fe3a4dabf40d298cf Mon Sep 17 00:00:00 2001
From: Jannik Silvanus <jannik.silvanus at amd.com>
Date: Thu, 21 Mar 2024 18:50:37 +0100
Subject: [PATCH 2/2] update_test_checks: Fix preservation of meta variable
 names with --include-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.
---
 .../Inputs/stable_ir_values5.ll.expected      | 10 +-
 llvm/utils/UpdateTestChecks/common.py         | 91 ++++++++++++++-----
 2 files changed, 73 insertions(+), 28 deletions(-)

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
index 50c883f55a4673..09df76d9dadc62 100644
--- 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
@@ -15,9 +15,9 @@ define i32 @func({i32, i32} %x, i32 %y) {
 
 ; CHECK-LABEL: define i32 @func(
 ; CHECK-SAME: { i32, i32 } [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT:    [[X_I34:%.*]] = extractvalue { i32, i32 } [[X]], 0
-; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[Y]], 1
-; CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[X_I34]], [[TMP1]]
-; CHECK-NEXT:    [[TMP3:%.*]] = mul i32 [[TMP2]], 3
-; CHECK-NEXT:    ret i32 [[TMP3]]
+; 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/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py
index ecb19d233a8d1a..f0cf73ec5b0eaa 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
 



More information about the llvm-commits mailing list