[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 06:45:22 PDT 2025
https://github.com/Camsyn updated https://github.com/llvm/llvm-project/pull/165718
>From 0a1019144f8a74e1b5f5b949c55a8872a8915317 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/7] [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 119303c319246..48f82b563f596 100644
--- a/llvm/utils/UpdateTestChecks/common.py
+++ b/llvm/utils/UpdateTestChecks/common.py
@@ -2292,42 +2292,24 @@ def add_checks(
ignore_all_comments=not check_inst_comments,
)
- # 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
if not check_inst_comments:
# Do not waste time checking IR comments unless necessary.
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 80f8e57c5691e75b28a85b81b7a5a2a6409a4638 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/7] 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 0169a6732bdaf7b196527479db978b94ace12b1b 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/7] 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 48f82b563f596..d0932c28b207e 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
@@ -2292,24 +2292,47 @@ def add_checks(
ignore_all_comments=not check_inst_comments,
)
+ # 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
if not check_inst_comments:
# Do not waste time checking IR comments unless necessary.
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.
>From b990bd968f05423582305cb61fc7ba6112c682fc Mon Sep 17 00:00:00 2001
From: Camsyn <camsyn at foxmail.com>
Date: Fri, 31 Oct 2025 21:05:03 +0800
Subject: [PATCH 4/7] Regenerate a test
---
.../Inputs/switch_case.ll.expected | 36 ++++++++++++-------
1 file changed, 24 insertions(+), 12 deletions(-)
diff --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/switch_case.ll.expected b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/switch_case.ll.expected
index b1977e7ae2ee2..8cab0bbf304f3 100644
--- a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/switch_case.ll.expected
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/switch_case.ll.expected
@@ -12,13 +12,17 @@ define i8 @testi8(i8 %x) {
; CHECK-NEXT: i8 2, label %[[CASE3:.*]]
; CHECK-NEXT: i8 3, label %[[CASE3]]
; CHECK-NEXT: ]
-; CHECK: [[DEFAULT]]:
+; CHECK-EMPTY:
+; CHECK-NEXT: [[DEFAULT]]:
; CHECK-NEXT: ret i8 0
-; CHECK: [[CASE1]]:
+; CHECK-EMPTY:
+; CHECK-NEXT: [[CASE1]]:
; CHECK-NEXT: ret i8 1
-; CHECK: [[CASE2]]:
+; CHECK-EMPTY:
+; CHECK-NEXT: [[CASE2]]:
; CHECK-NEXT: ret i8 2
-; CHECK: [[CASE3]]:
+; CHECK-EMPTY:
+; CHECK-NEXT: [[CASE3]]:
; CHECK-NEXT: ret i8 3
;
switch i8 %x, label %default [
@@ -46,13 +50,17 @@ define i32 @testi32(i32 %x) {
; CHECK-NEXT: i32 2, label %[[CASE3:.*]]
; CHECK-NEXT: i32 3, label %[[CASE3]]
; CHECK-NEXT: ]
-; CHECK: [[DEFAULT]]:
+; CHECK-EMPTY:
+; CHECK-NEXT: [[DEFAULT]]:
; CHECK-NEXT: ret i32 0
-; CHECK: [[CASE1]]:
+; CHECK-EMPTY:
+; CHECK-NEXT: [[CASE1]]:
; CHECK-NEXT: ret i32 1
-; CHECK: [[CASE2]]:
+; CHECK-EMPTY:
+; CHECK-NEXT: [[CASE2]]:
; CHECK-NEXT: ret i32 2
-; CHECK: [[CASE3]]:
+; CHECK-EMPTY:
+; CHECK-NEXT: [[CASE3]]:
; CHECK-NEXT: ret i32 3
;
switch i32 %x, label %default [
@@ -80,13 +88,17 @@ define i128 @testi128(i128 %x) {
; CHECK-NEXT: i128 2, label %[[CASE3:.*]]
; CHECK-NEXT: i128 3, label %[[CASE3]]
; CHECK-NEXT: ]
-; CHECK: [[DEFAULT]]:
+; CHECK-EMPTY:
+; CHECK-NEXT: [[DEFAULT]]:
; CHECK-NEXT: ret i128 0
-; CHECK: [[CASE1]]:
+; CHECK-EMPTY:
+; CHECK-NEXT: [[CASE1]]:
; CHECK-NEXT: ret i128 1
-; CHECK: [[CASE2]]:
+; CHECK-EMPTY:
+; CHECK-NEXT: [[CASE2]]:
; CHECK-NEXT: ret i128 2
-; CHECK: [[CASE3]]:
+; CHECK-EMPTY:
+; CHECK-NEXT: [[CASE3]]:
; CHECK-NEXT: ret i128 3
;
switch i128 %x, label %default [
>From 2804b2c3e483be2101576bdd95655b463b89ef88 Mon Sep 17 00:00:00 2001
From: Camsyn <camsyn at foxmail.com>
Date: Fri, 31 Oct 2025 21:26:56 +0800
Subject: [PATCH 5/7] Distinguish 'Fake' blank lines
---
llvm/utils/UpdateTestChecks/common.py | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/llvm/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py
index d0932c28b207e..52d700bef0b75 100644
--- a/llvm/utils/UpdateTestChecks/common.py
+++ b/llvm/utils/UpdateTestChecks/common.py
@@ -2280,6 +2280,9 @@ def add_checks(
# For IR output, change all defs to FileCheck variables, so we're immune
# to variable naming fashions.
else:
+ blank_line_indices = {
+ i for i, line in enumerate(func_body) if line.strip() == ""
+ } if ginfo.get_version() >= 7 else set()
func_body = generalize_check_lines(
func_body,
ginfo,
@@ -2305,9 +2308,13 @@ def add_checks(
is_blank_line = False
- for func_line in func_body:
+ for idx, func_line in enumerate(func_body):
if func_line.strip() == "":
- if ginfo.get_version() >= 7:
+ # We should distinguish if the line is a 'fake' blank line generated by
+ # generalize_check_lines removing comments.
+ # Fortunately, generalize_check_lines does not change the index of each line,
+ # we can record the indices of blank lines preemptively.
+ if idx in blank_line_indices:
output_lines.append(
"{} {}-EMPTY:".format(comment_marker, checkprefix)
)
>From 895f1d9f464b20dc6196b8585a5f3d108ac54ce9 Mon Sep 17 00:00:00 2001
From: Camsyn <camsyn at foxmail.com>
Date: Fri, 31 Oct 2025 21:41:15 +0800
Subject: [PATCH 6/7] Make formatter happy
---
llvm/utils/UpdateTestChecks/common.py | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/llvm/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py
index 52d700bef0b75..04a0f9f62c16a 100644
--- a/llvm/utils/UpdateTestChecks/common.py
+++ b/llvm/utils/UpdateTestChecks/common.py
@@ -2280,9 +2280,12 @@ def add_checks(
# For IR output, change all defs to FileCheck variables, so we're immune
# to variable naming fashions.
else:
- blank_line_indices = {
- i for i, line in enumerate(func_body) if line.strip() == ""
- } if ginfo.get_version() >= 7 else set()
+ if ginfo.get_version() >= 7:
+ # Record the indices of blank lines in the function body preemptively.
+ blank_line_indices = { i for i, line in enumerate(func_body) if line.strip() == "" }
+ else:
+ blank_line_indices = set()
+
func_body = generalize_check_lines(
func_body,
ginfo,
>From 6f0f7fb4c426ec04cbbf232f68d4372554b964ac Mon Sep 17 00:00:00 2001
From: Camsyn <camsyn at foxmail.com>
Date: Fri, 31 Oct 2025 21:45:04 +0800
Subject: [PATCH 7/7] Make formatter happy
---
llvm/utils/UpdateTestChecks/common.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/llvm/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py
index 04a0f9f62c16a..2dad16a8eebb7 100644
--- a/llvm/utils/UpdateTestChecks/common.py
+++ b/llvm/utils/UpdateTestChecks/common.py
@@ -2282,7 +2282,9 @@ def add_checks(
else:
if ginfo.get_version() >= 7:
# Record the indices of blank lines in the function body preemptively.
- blank_line_indices = { i for i, line in enumerate(func_body) if line.strip() == "" }
+ blank_line_indices = {
+ i for i, line in enumerate(func_body) if line.strip() == ""
+ }
else:
blank_line_indices = set()
More information about the llvm-commits
mailing list