[llvm] [UTC] CHECK-EMPTY instead of skipping blank lines (PR #165718)

Kunqiu Chen via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 31 04:53:31 PDT 2025


https://github.com/Camsyn updated https://github.com/llvm/llvm-project/pull/165718

>From 795b21788d85196643a68673b2c17a5920ed474e Mon Sep 17 00:00:00 2001
From: Camsyn <camsyn at foxmail.com>
Date: Thu, 30 Oct 2025 21:24:04 +0800
Subject: [PATCH 1/3] [UTC] CHECK-EMPTY instead of skiping blank lines

---
 llvm/utils/UpdateTestChecks/common.py | 36 +++++++--------------------
 1 file changed, 9 insertions(+), 27 deletions(-)

diff --git a/llvm/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py
index 8cd200c93a482..d9ef660ebdca8 100644
--- a/llvm/utils/UpdateTestChecks/common.py
+++ b/llvm/utils/UpdateTestChecks/common.py
@@ -2282,41 +2282,23 @@ def add_checks(
                     original_check_lines=original_check_lines.get(checkprefix),
                 )
 
-                # This could be selectively enabled with an optional invocation argument.
-                # Disabled for now: better to check everything. Be safe rather than sorry.
-
-                # Handle the first line of the function body as a special case because
-                # it's often just noise (a useless asm comment or entry label).
-                # if func_body[0].startswith("#") or func_body[0].startswith("entry:"):
-                #  is_blank_line = True
-                # else:
-                #  output_lines.append('%s %s:       %s' % (comment_marker, checkprefix, func_body[0]))
-                #  is_blank_line = False
-
-                is_blank_line = False
 
                 for func_line in func_body:
                     if func_line.strip() == "":
-                        is_blank_line = True
+                        # Instead of skipping blank lines, using CHECK_EMPTY is more defensive.
+                        output_lines.append(
+                            "{} {}-EMPTY:".format(comment_marker, checkprefix)
+                        )
                         continue
                     # Do not waste time checking IR comments.
                     func_line = SCRUB_IR_COMMENT_RE.sub(r"", func_line)
 
-                    # Skip blank lines instead of checking them.
-                    if is_blank_line:
-                        output_lines.append(
-                            "{} {}:       {}".format(
-                                comment_marker, checkprefix, func_line
-                            )
-                        )
-                    else:
-                        check_suffix = "-NEXT" if not is_filtered else ""
-                        output_lines.append(
-                            "{} {}{}:  {}".format(
-                                comment_marker, checkprefix, check_suffix, func_line
-                            )
+                    check_suffix = "-NEXT" if not is_filtered else ""
+                    output_lines.append(
+                        "{} {}{}:  {}".format(
+                            comment_marker, checkprefix, check_suffix, func_line
                         )
-                    is_blank_line = False
+                    )
 
                 # Add space between different check prefixes and also before the first
                 # line of code in the test function.

>From cb10fe64d391e01c41cc09da6fbc064506715587 Mon Sep 17 00:00:00 2001
From: Camsyn <camsyn at foxmail.com>
Date: Thu, 30 Oct 2025 21:24:17 +0800
Subject: [PATCH 2/3] Add a test

---
 .../update_test_checks/Inputs/check_empty.ll  | 29 ++++++++++
 .../Inputs/check_empty.ll.expected            | 57 +++++++++++++++++++
 .../update_test_checks/check_empty.test       |  3 +
 3 files changed, 89 insertions(+)
 create mode 100644 llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/check_empty.ll
 create mode 100644 llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/check_empty.ll.expected
 create mode 100644 llvm/test/tools/UpdateTestChecks/update_test_checks/check_empty.test

diff --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/check_empty.ll b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/check_empty.ll
new file mode 100644
index 0000000000000..abaa0ce2dd3b4
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/check_empty.ll
@@ -0,0 +1,29 @@
+; RUN: opt < %s -S | FileCheck %s
+
+; Test whether the UTC check empty lines instead of skipping them.
+define i32 @test(i32 %x) {
+entry:
+  br label %block1
+
+block1:
+  %cmp = icmp eq i32 %x, 0
+  br i1 %cmp, label %block2, label %exit1
+
+block2:
+  br i1 %cmp, label %block3, label %exit2
+
+block3:
+  br i1 %cmp, label %exit3, label %exit4
+
+exit1:
+  ret i32 0
+
+exit2:
+  ret i32 %x
+
+exit3:
+  ret i32 %x
+
+exit4:
+  ret i32 %x
+}
diff --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/check_empty.ll.expected b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/check_empty.ll.expected
new file mode 100644
index 0000000000000..dc2a37907039e
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/check_empty.ll.expected
@@ -0,0 +1,57 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -S | FileCheck %s
+
+; Test whether the UTC check empty lines instead of skipping them.
+define i32 @test(i32 %x) {
+; CHECK-LABEL: define i32 @test(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    br label %[[BLOCK1:.*]]
+; CHECK-EMPTY:
+; CHECK-NEXT:  [[BLOCK1]]:
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X]], 0
+; CHECK-NEXT:    br i1 [[CMP]], label %[[BLOCK2:.*]], label %[[EXIT1:.*]]
+; CHECK-EMPTY:
+; CHECK-NEXT:  [[BLOCK2]]:
+; CHECK-NEXT:    br i1 [[CMP]], label %[[BLOCK3:.*]], label %[[EXIT2:.*]]
+; CHECK-EMPTY:
+; CHECK-NEXT:  [[BLOCK3]]:
+; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT3:.*]], label %[[EXIT4:.*]]
+; CHECK-EMPTY:
+; CHECK-NEXT:  [[EXIT1]]:
+; CHECK-NEXT:    ret i32 0
+; CHECK-EMPTY:
+; CHECK-NEXT:  [[EXIT2]]:
+; CHECK-NEXT:    ret i32 [[X]]
+; CHECK-EMPTY:
+; CHECK-NEXT:  [[EXIT3]]:
+; CHECK-NEXT:    ret i32 [[X]]
+; CHECK-EMPTY:
+; CHECK-NEXT:  [[EXIT4]]:
+; CHECK-NEXT:    ret i32 [[X]]
+;
+entry:
+  br label %block1
+
+block1:
+  %cmp = icmp eq i32 %x, 0
+  br i1 %cmp, label %block2, label %exit1
+
+block2:
+  br i1 %cmp, label %block3, label %exit2
+
+block3:
+  br i1 %cmp, label %exit3, label %exit4
+
+exit1:
+  ret i32 0
+
+exit2:
+  ret i32 %x
+
+exit3:
+  ret i32 %x
+
+exit4:
+  ret i32 %x
+}
diff --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/check_empty.test b/llvm/test/tools/UpdateTestChecks/update_test_checks/check_empty.test
new file mode 100644
index 0000000000000..61e85152db951
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/check_empty.test
@@ -0,0 +1,3 @@
+## test whether the UTC generates CHECK-EMPTY for blank lines
+# RUN: cp -f %S/Inputs/check_empty.ll %t.ll && %update_test_checks %t.ll
+# RUN: diff -u %t.ll %S/Inputs/check_empty.ll.expected

>From 1748e4c8b50b1e7a7b6c912981b721ce62c4ec93 Mon Sep 17 00:00:00 2001
From: Camsyn <camsyn at foxmail.com>
Date: Fri, 31 Oct 2025 19:53:17 +0800
Subject: [PATCH 3/3] Gate the new change with version 7

---
 .../Inputs/check_empty.ll.expected            |  2 +-
 .../update_test_checks/check_empty.test       |  2 +-
 llvm/utils/UpdateTestChecks/common.py         | 43 ++++++++++++++-----
 3 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/check_empty.ll.expected b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/check_empty.ll.expected
index dc2a37907039e..f52687da3632b 100644
--- a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/check_empty.ll.expected
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/check_empty.ll.expected
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 7
 ; RUN: opt < %s -S | FileCheck %s
 
 ; Test whether the UTC check empty lines instead of skipping them.
diff --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/check_empty.test b/llvm/test/tools/UpdateTestChecks/update_test_checks/check_empty.test
index 61e85152db951..670bda27bb369 100644
--- a/llvm/test/tools/UpdateTestChecks/update_test_checks/check_empty.test
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/check_empty.test
@@ -1,3 +1,3 @@
 ## test whether the UTC generates CHECK-EMPTY for blank lines
-# RUN: cp -f %S/Inputs/check_empty.ll %t.ll && %update_test_checks %t.ll
+# RUN: cp -f %S/Inputs/check_empty.ll %t.ll && %update_test_checks %t.ll --version 7
 # RUN: diff -u %t.ll %S/Inputs/check_empty.ll.expected
diff --git a/llvm/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py
index d9ef660ebdca8..3f71822b16b25 100644
--- a/llvm/utils/UpdateTestChecks/common.py
+++ b/llvm/utils/UpdateTestChecks/common.py
@@ -29,7 +29,7 @@
    'none' and 'all'. 'smart' is the default.
 5: Basic block labels are matched by FileCheck expressions
 6: The semantics of TBAA checks has been incorporated in the check lines.
-7: Indent switch-cases correctly.
+7: Indent switch-cases correctly; CHECK-EMPTY instead of skipping blank lines.
 """
 DEFAULT_VERSION = 6
 
@@ -2282,23 +2282,46 @@ def add_checks(
                     original_check_lines=original_check_lines.get(checkprefix),
                 )
 
+                # This could be selectively enabled with an optional invocation argument.
+                # Disabled for now: better to check everything. Be safe rather than sorry.
+
+                # Handle the first line of the function body as a special case because
+                # it's often just noise (a useless asm comment or entry label).
+                # if func_body[0].startswith("#") or func_body[0].startswith("entry:"):
+                #  is_blank_line = True
+                # else:
+                #  output_lines.append('%s %s:       %s' % (comment_marker, checkprefix, func_body[0]))
+                #  is_blank_line = False
+
+                is_blank_line = False
 
                 for func_line in func_body:
                     if func_line.strip() == "":
-                        # Instead of skipping blank lines, using CHECK_EMPTY is more defensive.
-                        output_lines.append(
-                            "{} {}-EMPTY:".format(comment_marker, checkprefix)
-                        )
+                        if ginfo.get_version() >= 7:
+                            output_lines.append(
+                                "{} {}-EMPTY:".format(comment_marker, checkprefix)
+                            )
+                        else:
+                            is_blank_line = True
                         continue
                     # Do not waste time checking IR comments.
                     func_line = SCRUB_IR_COMMENT_RE.sub(r"", func_line)
 
-                    check_suffix = "-NEXT" if not is_filtered else ""
-                    output_lines.append(
-                        "{} {}{}:  {}".format(
-                            comment_marker, checkprefix, check_suffix, func_line
+                    # Skip blank lines instead of checking them.
+                    if is_blank_line:
+                        output_lines.append(
+                            "{} {}:       {}".format(
+                                comment_marker, checkprefix, func_line
+                            )
                         )
-                    )
+                    else:
+                        check_suffix = "-NEXT" if not is_filtered else ""
+                        output_lines.append(
+                            "{} {}{}:  {}".format(
+                                comment_marker, checkprefix, check_suffix, func_line
+                            )
+                        )
+                    is_blank_line = False
 
                 # Add space between different check prefixes and also before the first
                 # line of code in the test function.



More information about the llvm-commits mailing list