[llvm] [llvm-utils][Tools] fix mir-check filter to handle scattered check-lines (PR #209226)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 13 08:46:05 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-testing-tools

Author: Gang Chen (cmc-rep)

<details>
<summary>Changes</summary>



---
Full diff: https://github.com/llvm/llvm-project/pull/209226.diff


3 Files Affected:

- (modified) llvm/test/tools/UpdateTestChecks/update_mir_test_checks/Inputs/x86-filter.mir.filter-out.expected (+2-2) 
- (modified) llvm/test/tools/UpdateTestChecks/update_mir_test_checks/Inputs/x86-filter.mir.filter.expected (+4-1) 
- (modified) llvm/utils/UpdateTestChecks/mir.py (+63-2) 


``````````diff
diff --git a/llvm/test/tools/UpdateTestChecks/update_mir_test_checks/Inputs/x86-filter.mir.filter-out.expected b/llvm/test/tools/UpdateTestChecks/update_mir_test_checks/Inputs/x86-filter.mir.filter-out.expected
index 87c3670a10421..ea924dd74d398 100644
--- a/llvm/test/tools/UpdateTestChecks/update_mir_test_checks/Inputs/x86-filter.mir.filter-out.expected
+++ b/llvm/test/tools/UpdateTestChecks/update_mir_test_checks/Inputs/x86-filter.mir.filter-out.expected
@@ -32,7 +32,7 @@ body:             |
     ; CHECK-LABEL: name: ptrtoint_s8
     ; CHECK: liveins: $rdi
     ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: $al = COPY [[COPY1]]
+    ; CHECK: $al = COPY [[COPY1]]
     ; CHECK-NEXT: RET 0, implicit $al
     %0:gpr(p0) = COPY $rdi
     %1:gpr(s8) = G_PTRTOINT %0(p0)
@@ -57,7 +57,7 @@ body:             |
     ; CHECK: liveins: $rdi
     ; CHECK-NEXT: {{  $}}
     ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi
-    ; CHECK-NEXT: $eax = COPY [[COPY1]]
+    ; CHECK: $eax = COPY [[COPY1]]
     ; CHECK-NEXT: RET 0, implicit $eax
     %0:gpr(p0) = COPY $rdi
     %1:gpr(s32) = G_PTRTOINT %0(p0)
diff --git a/llvm/test/tools/UpdateTestChecks/update_mir_test_checks/Inputs/x86-filter.mir.filter.expected b/llvm/test/tools/UpdateTestChecks/update_mir_test_checks/Inputs/x86-filter.mir.filter.expected
index 39064f9a3ae3c..4141015cf9059 100644
--- a/llvm/test/tools/UpdateTestChecks/update_mir_test_checks/Inputs/x86-filter.mir.filter.expected
+++ b/llvm/test/tools/UpdateTestChecks/update_mir_test_checks/Inputs/x86-filter.mir.filter.expected
@@ -30,7 +30,8 @@ body:             |
     liveins: $rdi
 
     ; CHECK-LABEL: name: ptrtoint_s8
-    ; CHECK: [[COPY1:%[0-9]+]]:gr8 = COPY [[COPY]].sub_8bit
+    ; CHECK: [[COPY:%[0-9]+]]:gr64_with_sub_8bit = COPY $rdi
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr8 = COPY [[COPY]].sub_8bit
     %0:gpr(p0) = COPY $rdi
     %1:gpr(s8) = G_PTRTOINT %0(p0)
     $al = COPY %1(s8)
@@ -50,6 +51,8 @@ body:             |
   bb.1.entry:
     liveins: $rdi
 
+    ; CHECK-LABEL: name: ptrtoint_s32
+    ; CHECK: [[COPY1:%[0-9]+]]:gr32 = COPY [[COPY]].sub_32bit
     %0:gpr(p0) = COPY $rdi
     %1:gpr(s32) = G_PTRTOINT %0(p0)
     $eax = COPY %1(s32)
diff --git a/llvm/utils/UpdateTestChecks/mir.py b/llvm/utils/UpdateTestChecks/mir.py
index e75d3dd2ff368..5b269167b8db8 100644
--- a/llvm/utils/UpdateTestChecks/mir.py
+++ b/llvm/utils/UpdateTestChecks/mir.py
@@ -50,6 +50,52 @@
     flags=(re.M | re.S),
 )
 
+MD_PTR_RE = re.compile(r"\<0x[a-f0-9]+\>", re.IGNORECASE)
+
+# A marker inserted into a filtered MIR function body to record that one or more
+# lines were removed by --filter between two retained lines. When emitting
+# checks, the retained line that follows a marker is printed as CHECK (rather
+# than CHECK-NEXT) because it is not guaranteed to immediately follow the
+# previous match in the tool output.
+MIR_FILTER_GAP_MARKER = "; UTC-MIR-FILTER-GAP"
+
+
+def filter_mir_body(body, filters):
+    """Filter a MIR function body while keeping the generated checks correct.
+
+    Behaves like common.do_filter, with two MIR-specific adjustments that make
+    --filter usable for tests whose interesting instructions are scattered
+    through the function:
+
+      * Basic block label lines are always retained.  This keeps the check
+        comments at the block-level indentation (so the surrounding "body: |"
+        block scalar stays valid) and documents the control-flow structure.
+      * A marker line is inserted wherever one or more lines were removed
+        between two retained lines.  add_mir_check_lines turns the retained line
+        after a marker into a CHECK instead of a CHECK-NEXT, since filtered-out
+        instructions may sit between the two matches in the tool output.
+    """
+    if not filters:
+        return body
+    if common.has_filter_out_after(filters):
+        lines = common.filter_out_after(body, filters)
+    else:
+        lines = body.splitlines()
+    result = []
+    have_gap = False
+    for line in lines:
+        keep = common.apply_filters(line, filters) or bool(
+            MIR_BASIC_BLOCK_RE.match(line)
+        )
+        if not keep:
+            have_gap = True
+            continue
+        if have_gap and result:
+            result.append(MIR_FILTER_GAP_MARKER)
+        result.append(line)
+        have_gap = False
+    return "\n".join(result)
+
 
 def build_function_info_dictionary(
     test, raw_tool_output, triple, prefixes, func_dict, verbose, filters=None
@@ -84,7 +130,7 @@ def build_function_info_dictionary(
                 )
             mangled.append(func_line)
         body = "".join(mangled)
-        filtered_body = common.do_filter(body, filters)
+        filtered_body = filter_mir_body(body, filters)
 
         for prefix in prefixes:
             info = common.function_body(
@@ -215,6 +261,12 @@ def add_mir_check_lines(
         # Don't bother checking the basic block label for a single BB
         func_body.pop(0)
 
+    # A gap marker carries no information before the first retained line, and
+    # popping the basic block label above may have exposed one.  Drop any such
+    # leading markers so indentation is computed from a real instruction line.
+    while func_body and func_body[0] == MIR_FILTER_GAP_MARKER:
+        func_body.pop(0)
+
     if not func_body:
         warn(
             "Function has no instructions to check: {}".format(func_name),
@@ -240,6 +292,12 @@ def add_mir_check_lines(
 
     first_check = not first_check_is_next
     for func_line in func_body:
+        if func_line == MIR_FILTER_GAP_MARKER:
+            # One or more lines were filtered out here, so the next retained
+            # line is not necessarily adjacent to the previous match: emit it as
+            # CHECK rather than CHECK-NEXT.
+            first_check = True
+            continue
         if not func_line.strip():
             # The mir printer prints leading whitespace so we can't use CHECK-EMPTY:
             output_lines.append(check + "-NEXT: {{" + func_line + "$}}")
@@ -277,7 +335,10 @@ def add_mir_checks(
     func_name = None
     state = "toplevel"
     for input_line in input_lines:
-        if input_line == autogenerated_note:
+        if common.UTC_ADVERT in input_line:
+            # Discard any previous autogenerated note.  Matching on the advert
+            # text (rather than the exact note) ensures a stale note is dropped
+            # even when the arguments differ, e.g. when --filter was added.
             continue
 
         if state == "toplevel":

``````````

</details>


https://github.com/llvm/llvm-project/pull/209226


More information about the llvm-commits mailing list