https://github.com/jofrn updated https://github.com/llvm/llvm-project/pull/200351
>From 841be175774ff0a848ba930d8876d68d47958855 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
