https://github.com/matteo-rm created 
https://github.com/llvm/llvm-project/pull/237599

NOTE: Since the minimum supported version is Python 3.8, `dict.items()` returns 
elements in insertion order and the substitutions can be done in reverse order.

NOTE2: This will be useful if we eventually want to auto-generate e.g. CIR 
tests (which currently rely on this).

From d47b930ab467983e95f3e839d883eb79a2507d3b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matt=C3=A9o=20Rizza=20Murgier?=
 <[email protected]>
Date: Sat, 31 Oct 2026 18:49:42 +0100
Subject: [PATCH] [UpdateTestChecks] Add support for (RE)DEFINE directives

---
 .../update_cc_test_checks/Inputs/define.c     |  8 +++++
 .../Inputs/define.c.expected                  | 19 ++++++++++++
 .../utils/update_cc_test_checks/define.test   |  4 +++
 llvm/utils/UpdateTestChecks/common.py         | 31 ++++++++++++++++---
 4 files changed, 57 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/utils/update_cc_test_checks/Inputs/define.c
 create mode 100644 
clang/test/utils/update_cc_test_checks/Inputs/define.c.expected
 create mode 100644 clang/test/utils/update_cc_test_checks/define.test

diff --git a/clang/test/utils/update_cc_test_checks/Inputs/define.c 
b/clang/test/utils/update_cc_test_checks/Inputs/define.c
new file mode 100644
index 00000000000000..bb4cf2d38a2d30
--- /dev/null
+++ b/clang/test/utils/update_cc_test_checks/Inputs/define.c
@@ -0,0 +1,8 @@
+// Check that DEFINE and REDEFINE substitutions are expanded in RUN lines.
+// DEFINE: %{optimize} = opt -passes=mem2reg \
+// DEFINE:   -S
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -disable-O0-optnone 
-emit-llvm %s -o - | %{optimize} | FileCheck %s --check-prefix=MEM2REG
+// REDEFINE: %{optimize} = opt -passes=mem2reg,instcombine -S
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -disable-O0-optnone 
-emit-llvm %s -o - | %{optimize} | FileCheck %s --check-prefix=INSTCOMBINE
+
+int f(int a) { return (a + 1) - 1; }
diff --git a/clang/test/utils/update_cc_test_checks/Inputs/define.c.expected 
b/clang/test/utils/update_cc_test_checks/Inputs/define.c.expected
new file mode 100644
index 00000000000000..c3927c753b6544
--- /dev/null
+++ b/clang/test/utils/update_cc_test_checks/Inputs/define.c.expected
@@ -0,0 +1,19 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// Check that DEFINE and REDEFINE substitutions are expanded in RUN lines.
+// DEFINE: %{optimize} = opt -passes=mem2reg \
+// DEFINE:   -S
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -disable-O0-optnone 
-emit-llvm %s -o - | %{optimize} | FileCheck %s --check-prefix=MEM2REG
+// REDEFINE: %{optimize} = opt -passes=mem2reg,instcombine -S
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -disable-O0-optnone 
-emit-llvm %s -o - | %{optimize} | FileCheck %s --check-prefix=INSTCOMBINE
+
+// MEM2REG-LABEL: @f(
+// MEM2REG-NEXT:  entry:
+// MEM2REG-NEXT:    [[ADD:%.*]] = add nsw i32 [[A:%.*]], 1
+// MEM2REG-NEXT:    [[SUB:%.*]] = sub nsw i32 [[ADD]], 1
+// MEM2REG-NEXT:    ret i32 [[SUB]]
+//
+// INSTCOMBINE-LABEL: @f(
+// INSTCOMBINE-NEXT:  entry:
+// INSTCOMBINE-NEXT:    ret i32 [[A:%.*]]
+//
+int f(int a) { return (a + 1) - 1; }
diff --git a/clang/test/utils/update_cc_test_checks/define.test 
b/clang/test/utils/update_cc_test_checks/define.test
new file mode 100644
index 00000000000000..99c1c839a1d3e3
--- /dev/null
+++ b/clang/test/utils/update_cc_test_checks/define.test
@@ -0,0 +1,4 @@
+## Test that DEFINE and REDEFINE substitutions are expanded in RUN lines.
+
+# RUN: cp %S/Inputs/define.c %t.c && %update_cc_test_checks %t.c
+# RUN: diff -u %S/Inputs/define.c.expected %t.c
diff --git a/llvm/utils/UpdateTestChecks/common.py 
b/llvm/utils/UpdateTestChecks/common.py
index 2afa6072e1d379..757f2f48d54b03 100644
--- a/llvm/utils/UpdateTestChecks/common.py
+++ b/llvm/utils/UpdateTestChecks/common.py
@@ -578,6 +578,7 @@ def invoke_tool(exe, cmd_args, ir, preprocess_cmd=None, 
verbose=False):
 
 ##### LLVM IR parser
 RUN_LINE_RE = re.compile(r"^\s*(?://|[;#])\s*RUN:\s*(.*)$")
+DEFINE_LINE_RE = re.compile(r"^\s*(?://|[;#])\s*(?:RE)?DEFINE:\s*(.*)$")
 CHECK_PREFIX_RE = re.compile(r"--?check-prefix(?:es)?[= ](\S+)")
 PREFIX_RE = re.compile("^[a-zA-Z0-9_-]+$")
 CHECK_RE = re.compile(
@@ -672,12 +673,32 @@ def debug(*args, **kwargs):
 
 def find_run_lines(test, lines):
     debug("Scanning for RUN lines in test file:", test)
-    raw_lines = [m.group(1) for m in [RUN_LINE_RE.match(l) for l in lines] if 
m]
-    run_lines = [raw_lines[0]] if len(raw_lines) > 0 else []
-    for l in raw_lines[1:]:
-        if run_lines[-1].endswith("\\"):
-            run_lines[-1] = run_lines[-1].rstrip("\\") + " " + l
+    # Collect run and (re)define lines.
+    directives = []
+    for l in lines:
+        m = RUN_LINE_RE.match(l) or DEFINE_LINE_RE.match(l)
+        if not m:
+            continue
+        is_define = m.re is DEFINE_LINE_RE
+        if (
+            directives
+            and directives[-1][0] == is_define
+            and directives[-1][1].endswith("\\")
+        ):
+            directives[-1][1] = directives[-1][1].rstrip("\\") + " " + 
m.group(1)
+        else:
+            directives.append([is_define, m.group(1)])
+
+    # Substitute into run lines.
+    substitutions = {}
+    run_lines = []
+    for is_define, l in directives:
+        if is_define:
+            name, value = l.split("=", 1)
+            substitutions[name.strip()] = value.strip()
         else:
+            for name, value in reversed(substitutions.items()):
+                l = l.replace(name, value)
             run_lines.append(l)
     debug("Found {} RUN lines in {}:".format(len(run_lines), test))
     for l in run_lines:

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to