https://github.com/jofrn updated 
https://github.com/llvm/llvm-project/pull/200351

>From c9bcb5a43056ec339848696829982a0eabb60199 Mon Sep 17 00:00:00 2001
From: jofrn <[email protected]>
Date: Fri, 29 May 2026 01:12:01 -0700
Subject: [PATCH] [lit] Add lit.llvm.fn_extract: --param fn=NAMES prepends
 llvm-extract

---
 llvm/utils/lit/lit/llvm/fn_extract.py         | 19 ++++++++++++++
 llvm/utils/lit/lit/llvm/fn_param.py           |  6 ++---
 .../utils/lit/tests/Inputs/fn-extract/lit.cfg | 19 ++++++++++++++
 .../Inputs/fn-extract/mock-bin/llvm-extract   |  2 ++
 .../fn-extract/mock-bin/llvm-extract.bat      |  1 +
 .../lit/tests/Inputs/fn-extract/sample.ll     |  2 ++
 .../lit/tests/Inputs/fn-filter-checks/lit.cfg | 15 +++++++++++
 .../tests/Inputs/fn-filter-checks/sample.ll   | 17 ++++++++++++
 llvm/utils/lit/tests/fn-extract.py            | 26 +++++++++++++++++++
 llvm/utils/lit/tests/fn-filter-checks.py      | 10 +++++++
 10 files changed, 114 insertions(+), 3 deletions(-)
 create mode 100644 llvm/utils/lit/lit/llvm/fn_extract.py
 create mode 100644 llvm/utils/lit/tests/Inputs/fn-extract/lit.cfg
 create mode 100755 llvm/utils/lit/tests/Inputs/fn-extract/mock-bin/llvm-extract
 create mode 100644 
llvm/utils/lit/tests/Inputs/fn-extract/mock-bin/llvm-extract.bat
 create mode 100644 llvm/utils/lit/tests/Inputs/fn-extract/sample.ll
 create mode 100644 llvm/utils/lit/tests/Inputs/fn-filter-checks/lit.cfg
 create mode 100644 llvm/utils/lit/tests/Inputs/fn-filter-checks/sample.ll
 create mode 100644 llvm/utils/lit/tests/fn-extract.py
 create mode 100644 llvm/utils/lit/tests/fn-filter-checks.py

diff --git a/llvm/utils/lit/lit/llvm/fn_extract.py 
b/llvm/utils/lit/lit/llvm/fn_extract.py
new file mode 100644
index 0000000000000..f7d7f1d236a07
--- /dev/null
+++ b/llvm/utils/lit/lit/llvm/fn_extract.py
@@ -0,0 +1,19 @@
+"""Prepend `llvm-extract --func=NAME %s -o -` to the first pipeline stage of
+every RUN line that reads from `%s`, so subsequent tools (opt/llc/llvm-as/...)
+operate on a module narrowed to the named functions and their transitive
+dependencies. Tool-agnostic. Driven by `--param fn=NAMES`."""
+
+from lit.llvm.fn_param import add_capture_sub, parse_fn_names
+
+
+def install(config, lit_config):
+    names = parse_fn_names(lit_config)
+    if not names:
+        return
+    extract = "llvm-extract " + " ".join("--func=" + n for n in names) + " %s 
-o -"
+    # Match: optional %dbg(...) marker, then the first pipeline stage up to
+    # (but not crossing) the first `|`, ending with `< %s` or bare `%s`.
+    # `\s*` immediately before `%s` is consumed so we don't leave a double
+    # space after stripping the redirect/positional.
+    pattern = r"^(%dbg\([^)]*\)\s*)?([^|]*?)\s*(?:<\s*)?%s(?=\s|$)"
+    add_capture_sub(config, pattern, r"\1" + extract + r" | \2")
diff --git a/llvm/utils/lit/lit/llvm/fn_param.py 
b/llvm/utils/lit/lit/llvm/fn_param.py
index 48d8400b80155..ac0d4eb619693 100644
--- a/llvm/utils/lit/lit/llvm/fn_param.py
+++ b/llvm/utils/lit/lit/llvm/fn_param.py
@@ -41,6 +41,6 @@ def install(config, lit_config):
         # fn_selection.install(config, lit_config)
         pass
     else:
-        # from lit.llvm import fn_extract
-        # fn_extract.install(config, lit_config)
-        pass
+        from lit.llvm import fn_extract
+
+        fn_extract.install(config, lit_config)
diff --git a/llvm/utils/lit/tests/Inputs/fn-extract/lit.cfg 
b/llvm/utils/lit/tests/Inputs/fn-extract/lit.cfg
new file mode 100644
index 0000000000000..4452e2f71829c
--- /dev/null
+++ b/llvm/utils/lit/tests/Inputs/fn-extract/lit.cfg
@@ -0,0 +1,19 @@
+import lit.formats
+from lit.llvm import fn_param
+
+config.name = "fn-extract"
+config.suffixes = [".ll"]
+config.test_format = lit.formats.ShTest()
+config.test_source_root = None
+config.test_exec_root = None
+
+# Make a fake `llvm-extract` (exits 0) discoverable, so the prepended pipeline
+# stage succeeds and lit's -a output shows the substituted command line for
+# FileCheck to inspect.
+config.environment["PATH"] = (
+    os.path.join(os.path.dirname(__file__), "mock-bin")
+    + os.pathsep
+    + config.environment.get("PATH", "")
+)
+
+fn_param.install(config, lit_config)
diff --git a/llvm/utils/lit/tests/Inputs/fn-extract/mock-bin/llvm-extract 
b/llvm/utils/lit/tests/Inputs/fn-extract/mock-bin/llvm-extract
new file mode 100755
index 0000000000000..039e4d0069c5c
--- /dev/null
+++ b/llvm/utils/lit/tests/Inputs/fn-extract/mock-bin/llvm-extract
@@ -0,0 +1,2 @@
+#!/bin/sh
+exit 0
diff --git a/llvm/utils/lit/tests/Inputs/fn-extract/mock-bin/llvm-extract.bat 
b/llvm/utils/lit/tests/Inputs/fn-extract/mock-bin/llvm-extract.bat
new file mode 100644
index 0000000000000..dd161e028fee9
--- /dev/null
+++ b/llvm/utils/lit/tests/Inputs/fn-extract/mock-bin/llvm-extract.bat
@@ -0,0 +1 @@
+@exit /b 0
diff --git a/llvm/utils/lit/tests/Inputs/fn-extract/sample.ll 
b/llvm/utils/lit/tests/Inputs/fn-extract/sample.ll
new file mode 100644
index 0000000000000..d1c6ec435d53e
--- /dev/null
+++ b/llvm/utils/lit/tests/Inputs/fn-extract/sample.ll
@@ -0,0 +1,2 @@
+; RUN: echo opt %s -S -passes='instcombine' | echo FileCheck %s
+; RUN: echo opt < %s -S -passes="instcombine" | echo FileCheck %s
diff --git a/llvm/utils/lit/tests/Inputs/fn-filter-checks/lit.cfg 
b/llvm/utils/lit/tests/Inputs/fn-filter-checks/lit.cfg
new file mode 100644
index 0000000000000..f09191b2748ec
--- /dev/null
+++ b/llvm/utils/lit/tests/Inputs/fn-filter-checks/lit.cfg
@@ -0,0 +1,15 @@
+import lit.formats
+import shutil
+from lit.llvm import fn_param
+
+config.name = "fn-filter-checks"
+config.suffixes = [".ll"]
+config.test_format = lit.formats.ShTest()
+config.test_source_root = None
+config.test_exec_root = None
+
+for tool in ("opt", "llvm-extract", "FileCheck"):
+    if shutil.which(tool):
+        config.available_features.add(tool)
+
+fn_param.install(config, lit_config)
diff --git a/llvm/utils/lit/tests/Inputs/fn-filter-checks/sample.ll 
b/llvm/utils/lit/tests/Inputs/fn-filter-checks/sample.ll
new file mode 100644
index 0000000000000..eaa471b4f8c4a
--- /dev/null
+++ b/llvm/utils/lit/tests/Inputs/fn-filter-checks/sample.ll
@@ -0,0 +1,17 @@
+; REQUIRES: opt
+;
+; RUN: opt -S < %s -passes=instcombine | FileCheck %s
+
+define i32 @foo(i32 %x) {
+  ret i32 %x
+}
+
+define i32 @bar(i32 %x) {
+  ret i32 %x
+}
+
+; CHECK-LABEL: @foo
+; CHECK: ret i32 %x
+
+; CHECK-LABEL: @bar
+; CHECK: ret i32 FILTER_AWAY
diff --git a/llvm/utils/lit/tests/fn-extract.py 
b/llvm/utils/lit/tests/fn-extract.py
new file mode 100644
index 0000000000000..7411a44edacb5
--- /dev/null
+++ b/llvm/utils/lit/tests/fn-extract.py
@@ -0,0 +1,26 @@
+# Verify --param fn=NAMES prepends llvm-extract to the first pipeline stage
+# via lit.llvm.fn_extract (which is also wired into llvm/test/lit.cfg.py).
+
+# --- --param fn=foo: single function ---
+# RUN: %{lit} -a --param fn=foo %{inputs}/fn-extract/sample.ll \
+# RUN:   | FileCheck --check-prefix=SINGLE %s
+#
+# Positional `%s` form:
+# SINGLE: llvm-extract --func=foo {{.*}}sample.ll -o - | echo opt -S 
-passes='instcombine' | echo FileCheck {{.*}}sample.ll
+# Redirect `< %s` form:
+# SINGLE: llvm-extract --func=foo {{.*}}sample.ll -o - | echo opt -S 
-passes="instcombine" | echo FileCheck {{.*}}sample.ll
+
+# --- --param fn=foo,bar: multiple functions ---
+# RUN: %{lit} -a --param fn=foo,bar %{inputs}/fn-extract/sample.ll \
+# RUN:   | FileCheck --check-prefix=MULTI %s
+#
+# MULTI: llvm-extract --func=foo --func=bar {{.*}}sample.ll -o - | echo opt -S 
-passes='instcombine' | echo FileCheck {{.*}}sample.ll
+# MULTI: llvm-extract --func=foo --func=bar {{.*}}sample.ll -o - | echo opt -S 
-passes="instcombine" | echo FileCheck {{.*}}sample.ll
+
+# --- No --param: pipeline unchanged ---
+# RUN: %{lit} -a %{inputs}/fn-extract/sample.ll \
+# RUN:   | FileCheck --check-prefix=NONE %s
+#
+# NONE-NOT: llvm-extract
+# NONE: echo opt {{.*}}sample.ll -S -passes='instcombine'
+# NONE: echo opt < {{.*}}sample.ll -S -passes="instcombine"
diff --git a/llvm/utils/lit/tests/fn-filter-checks.py 
b/llvm/utils/lit/tests/fn-filter-checks.py
new file mode 100644
index 0000000000000..f9df86067e824
--- /dev/null
+++ b/llvm/utils/lit/tests/fn-filter-checks.py
@@ -0,0 +1,10 @@
+# Verify the end-to-end workflow: with `--param fn=NAMES`, llvm-extract narrows
+# the IR and `FileCheck --filter-label=NAMES` drops CHECKs for the removed
+# functions, so a CHECK that would otherwise fail is hidden.
+
+# With --param fn=foo: llvm-extract removes @bar;
+# --filter-label=foo is added to FileCheck, so the test passes.
+# RUN: %{lit} --param fn=foo %{inputs}/fn-filter-checks/sample.ll
+
+# Without --param fn=foo: @bar fails, so the test fails.
+# RUN: not %{lit} %{inputs}/fn-filter-checks/sample.ll

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

Reply via email to