[llvm] [UTC] Don't rename %. inside quoted strings in test checkseg (PR #218767)

Krzysztof Drewniak via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 25 21:38:49 PDT 2026


https://github.com/krzysz00 updated https://github.com/llvm/llvm-project/pull/218767

>From 2bb05719c303f3196514f0c55c50e6b10adf20db Mon Sep 17 00:00:00 2001
From: Krzysztof Drewniak <Krzysztof.Drewniak at amd.com>
Date: Thu, 20 Aug 2026 23:45:38 +0000
Subject: [PATCH] [utils] Don't rename %. inside quoted strings in test
 checkseg

Replacing `%.foo` with `%dotfoo` everywhere also caught any `%.foo`
inside metadata, which would then cause incorrect CHECK lines to be
generated (since the value in the metedata isn't going to be
modified).

This commit fixes the issue by matching quoted strings in a regex
before looking for %. to replace.

AI disclosure: Claude found and fixed this, I wrote the commit message
---
 .../Inputs/dot_value_in_metadata_string.ll    | 11 ++++++++++
 .../dot_value_in_metadata_string.ll.expected  | 22 +++++++++++++++++++
 .../dot_value_in_metadata_string.test         |  7 ++++++
 llvm/utils/UpdateTestChecks/common.py         | 11 +++++++++-
 4 files changed, 50 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/dot_value_in_metadata_string.ll
 create mode 100644 llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/dot_value_in_metadata_string.ll.expected
 create mode 100644 llvm/test/tools/UpdateTestChecks/update_test_checks/dot_value_in_metadata_string.test

diff --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/dot_value_in_metadata_string.ll b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/dot_value_in_metadata_string.ll
new file mode 100644
index 0000000000000..844a1087b61cf
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/dot_value_in_metadata_string.ll
@@ -0,0 +1,11 @@
+; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
+
+define i32 @dot_value_and_metadata_string(ptr %p, i32 %n) {
+  %.sum = add i32 %n, 1
+  store i32 %.sum, ptr %p, align 4, !alias.scope !0
+  ret i32 %.sum
+}
+
+!0 = !{!1}
+!1 = distinct !{!1, !2, !"callee: %.arg"}
+!2 = distinct !{!2, !"callee"}
diff --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/dot_value_in_metadata_string.ll.expected b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/dot_value_in_metadata_string.ll.expected
new file mode 100644
index 0000000000000..2fc57109e00d0
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/dot_value_in_metadata_string.ll.expected
@@ -0,0 +1,22 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals
+; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
+
+define i32 @dot_value_and_metadata_string(ptr %p, i32 %n) {
+; CHECK-LABEL: @dot_value_and_metadata_string(
+; CHECK-NEXT:    [[DOTSUM:%.*]] = add i32 [[N:%.*]], 1
+; CHECK-NEXT:    store i32 [[DOTSUM]], ptr [[P:%.*]], align 4, !alias.scope [[META0:![0-9]+]]
+; CHECK-NEXT:    ret i32 [[DOTSUM]]
+;
+  %.sum = add i32 %n, 1
+  store i32 %.sum, ptr %p, align 4, !alias.scope !0
+  ret i32 %.sum
+}
+
+!0 = !{!1}
+!1 = distinct !{!1, !2, !"callee: %.arg"}
+!2 = distinct !{!2, !"callee"}
+;.
+; CHECK: [[META0]] = !{[[META1:![0-9]+]]}
+; CHECK: [[META1]] = distinct !{[[META1]], [[META2:![0-9]+]], !"callee: %.arg"}
+; CHECK: [[META2]] = distinct !{[[META2]], !"callee"}
+;.
diff --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/dot_value_in_metadata_string.test b/llvm/test/tools/UpdateTestChecks/update_test_checks/dot_value_in_metadata_string.test
new file mode 100644
index 0000000000000..a61f093cf7091
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/dot_value_in_metadata_string.test
@@ -0,0 +1,7 @@
+# Verify that an IR value whose name starts with a '.' is still renamed to
+# derive a FileCheck variable name, while a '%.' inside a quoted metadata
+# string is left alone.
+# RUN: cp -f %S/Inputs/dot_value_in_metadata_string.ll %t.ll && %update_test_checks %t.ll --check-globals all
+# RUN: diff -u %t.ll %S/Inputs/dot_value_in_metadata_string.ll.expected
+# Verify that the generated check lines match the input they were taken from.
+# RUN: opt < %t.ll -passes=instsimplify -S | FileCheck %t.ll
diff --git a/llvm/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py
index fdd2e20d2f386..8305e32eafb92 100644
--- a/llvm/utils/UpdateTestChecks/common.py
+++ b/llvm/utils/UpdateTestChecks/common.py
@@ -1145,6 +1145,9 @@ def processed_prefixes(self, prefixes):
 # Comments to indicate the predecessors of a block in the IR.
 SCRUB_PRED_COMMENT_RE = re.compile(r"\s*; preds = .*")
 SCRUB_IR_FUNC_META_RE = re.compile(r"((?:\!(?!dbg\b)[a-zA-Z_]\w*(?:\s+![0-9]+)?)\s*)+")
+# A quoted string, or an IR variable whose name starts with a '.'. Matching the
+# strings too keeps the rename below from reaching inside one.
+IR_QUOTED_STRING_OR_DOT_VALUE_RE = re.compile(r"\"[^\"]*\"|%\.")
 
 # TODO: We should also derive check lines for global, debug, loop declarations, etc..
 
@@ -1927,7 +1930,13 @@ def escape_braces(match_obj):
     if ginfo.is_ir():
         for i, line in enumerate(lines):
             # An IR variable named '%.' matches the FileCheck regex string.
-            line = line.replace("%.", "%dot")
+            # Skip quoted strings: a '%.' inside one, as in the description of
+            # an alias scope named after a callee's argument, is text that
+            # nothing later generalizes away, so renaming it would leave a
+            # check line that cannot match the input it came from.
+            line = IR_QUOTED_STRING_OR_DOT_VALUE_RE.sub(
+                lambda m: m.group(0) if m.group(0).startswith('"') else "%dot", line
+            )
             for regex in _global_hex_value_regex:
                 if re.match("^@" + regex + " = ", line):
                     line = re.sub(



More information about the llvm-commits mailing list