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

via llvm-commits llvm-commits at lists.llvm.org
Sat Nov 1 02:01:35 PDT 2025


Author: Kunqiu Chen
Date: 2025-11-01T17:01:30+08:00
New Revision: 82cf54fbf6a7cd185cfe2279ca9d0cf4c4ea16e0

URL: https://github.com/llvm/llvm-project/commit/82cf54fbf6a7cd185cfe2279ca9d0cf4c4ea16e0
DIFF: https://github.com/llvm/llvm-project/commit/82cf54fbf6a7cd185cfe2279ca9d0cf4c4ea16e0.diff

LOG: [UTC] CHECK-EMPTY instead of skipping blank lines (#165718)

Previously, any blank lines in IR were ignored by UTC, leading to more
fragile `CHECK`s being generated.

This change lets UTC, 1) emit `CHECK-EMPTY` to check blank lines, and 2)
generate more `CHECK-NEXT`s, landing the discussion
https://github.com/llvm/llvm-project/pull/165419#issuecomment-3457572422.

Moreover, this change also aligns the behavior of IR check-gen to ASM
check-gen, which has been emitting `CHECK-EMPTY` since
https://github.com/llvm/llvm-project/commit/a8a89c77ea3c16b45763fca6940bbfd3bef7884f.

Added: 
    llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/check_empty.ll
    llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/check_empty.ll.expected
    llvm/test/tools/UpdateTestChecks/update_test_checks/check_empty.test

Modified: 
    llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/switch_case.ll.expected
    llvm/utils/UpdateTestChecks/common.py

Removed: 
    


################################################################################
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..bfd216d1ced49
--- /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 UTC checks 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..c5f822d10181a
--- /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 7
+; RUN: opt < %s -S | FileCheck %s
+
+; Test whether UTC checks 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/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 [

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..670bda27bb369
--- /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 --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 119303c319246..2dad16a8eebb7 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
 
@@ -2280,6 +2280,14 @@ def add_checks(
             # For IR output, change all defs to FileCheck variables, so we're immune
             # to variable naming fashions.
             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() == ""
+                    }
+                else:
+                    blank_line_indices = set()
+
                 func_body = generalize_check_lines(
                     func_body,
                     ginfo,
@@ -2305,9 +2313,18 @@ 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() == "":
-                        is_blank_line = True
+                        # 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)
+                            )
+                        else:
+                            is_blank_line = True
                         continue
                     if not check_inst_comments:
                         # Do not waste time checking IR comments unless necessary.


        


More information about the llvm-commits mailing list