[llvm] [lit] Add --filter-requires to select tests by required features (PR #221873)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 22 18:47:51 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-testing-tools
Author: Yasser Khan (yassermkhan)
<details>
<summary>Changes</summary>
### Overview
This PR provides a working solution for [RFC discussion 91864](https://discourse.llvm.org/t/91864).
`--filter-requires` selects tests using their existing REQUIRES expressions. It lets a caller request specific feature combinations without renaming tests, moving files or changing their requirements.
The implementation replaces the original regex proposal (see the RFC for the discussion). It reuses lit's BooleanExpression parser infrastructure while retaining the expression structure needed for matching.
### Behaviour
The filter selects tests using the requested features, not the device's reported capabilities. Tests are selected by matching their REQUIRES expressions against the filter, without checking whether those requirements are satisfied by available features. The caller must choose a suitable device. The flag does not change `available_features`. Lit still runs the test configuration files to set up tools, commands and available features. Any feature detection performed by those files is unchanged. UNSUPPORTED and XFAIL still use the configured features.
Expressions are expanded into combinations of required and excluded features. A test combination matches a filter combination when their required features are identical and the test adds no extra excluded features. This is intentionally different from ordinary feature satisfaction. A machine supporting Half and Int16 can normally run a test requiring only Half. Requesting `Half, Int16` with this option does not select that test. Feature names are case sensitive. Boolean operators and parentheses are supported. Commas and separate REQUIRES entries mean AND. Regex matching is not supported. An empty flag argument (`--filter-requires=""`) selects only tests without REQUIRES entries. Omitting the flag leaves normal lit behavior unchanged. Tests do not have to include the exclusions listed in the filter. Nonmatching tests receive EXCLUDED.
### Why this is useful
A test suite can contain tests with different requirements in the same directories. A caller may want to exercise one specific feature combination rather than everything a device can support. The availability bypass also allows attempts during feature development before a feature is advertised as supported. Running lit normally and examining the logs can identify skipped tests, but does not make those tests attempt execution. This option does not prove that a feature works or that the REQUIRES metadata is correct. It controls selection and allows matching tests past the availability check. Interpreting the results remains the caller's responsibility.
### Use Case
The initial use case is [LLVM's offload-test-suite](https://github.com/llvm/offload-test-suite). An external scheduler knows which features and combinations need to be tested and runs lit directly on a suitable device for each request. Tests without REQUIRES are run separately using `--filter-requires=""`, rather than repeated in every feature run. Keeping selection in lit avoids making the scheduler duplicate REQUIRES parsing.
### Examples
These examples describe selection. UNSUPPORTED and other existing checks can still prevent a selected test from running.
| Filter value | Test requirements | Selected |
|---|---|---|
| `Half` | `Half` | Yes |
| `Half` | `Half && Int16` | No |
| `Half, Int16` | `Half && Int16` | Yes |
| `Half, Int16` | `Half` | No |
| `Half` | `Half \|\| Int16` | Yes |
| `Half` | `Half && !Double` | No |
| `Half && !Double` | `Half && !Double` | Yes |
| `Half && !Double` | `Half` | Yes |
| `Half` | `Half && target=linux` | No |
| `""` (empty argument) | No requirements | Yes |
| `""` (empty argument) | `Half` | No |
| `Half` | No requirements | No |
| `Half \|\| Int16` | `Half` | Yes |
| `Half \|\| Int16` | `Int16` | Yes |
| `Half \|\| Int16` | `Half \|\| Int16` | Yes |
| `Half \|\| Int16` | `Half && Int16` | No |
Requests must include any positive target requirements in the matching combination. Omitted features are not wildcards.
### Testing results
The requirement matching unit tests, command line selection tests and WTT reporting tests pass locally on Windows. They cover exact matching, Boolean expressions, exclusions, empty flag arguments, invalid input, expansion limits and existing behavior without the flag.
### Sustainability
The caller maintains the requested feature expressions. When tests are added or their REQUIRES change, the caller checks that those requests still select the intended tests, updates them where needed and confirms that lit attempts the expected tests. New tests matching an existing request are selected automatically.
Lit maintainers would keep the filter working when the REQUIRES parser or test execution code changes. They would maintain tests for matching rules, errors and expression limits, and ensure runs without the flag behave as before.
Note: AI was used to create the tests and assisted in feature development.
---
Patch is 33.62 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/221873.diff
22 Files Affected:
- (modified) llvm/docs/CommandGuide/lit.md (+11)
- (added) llvm/utils/lit/lit/FilterRequires.py (+138)
- (modified) llvm/utils/lit/lit/Test.py (+3)
- (modified) llvm/utils/lit/lit/TestRunner.py (+29-8)
- (modified) llvm/utils/lit/lit/cl_arguments.py (+21)
- (modified) llvm/utils/lit/lit/main.py (+3)
- (modified) llvm/utils/lit/lit/reports.py (+7-1)
- (added) llvm/utils/lit/tests/Inputs/filter-requires/and.txt (+3)
- (added) llvm/utils/lit/tests/Inputs/filter-requires/features.txt (+5)
- (added) llvm/utils/lit/tests/Inputs/filter-requires/half.txt (+2)
- (added) llvm/utils/lit/tests/Inputs/filter-requires/lit.cfg (+10)
- (added) llvm/utils/lit/tests/Inputs/filter-requires/negative.txt (+2)
- (added) llvm/utils/lit/tests/Inputs/filter-requires/nested.txt (+3)
- (added) llvm/utils/lit/tests/Inputs/filter-requires/no-requires.txt (+1)
- (added) llvm/utils/lit/tests/Inputs/filter-requires/or.txt (+2)
- (added) llvm/utils/lit/tests/Inputs/filter-requires/regex.txt (+2)
- (added) llvm/utils/lit/tests/Inputs/filter-requires/true.txt (+2)
- (added) llvm/utils/lit/tests/Inputs/filter-requires/unsupported.txt (+3)
- (added) llvm/utils/lit/tests/Inputs/filter-requires/xfail.txt (+3)
- (added) llvm/utils/lit/tests/filter-requires-selection.py (+92)
- (modified) llvm/utils/lit/tests/test-output-wtt.py (+32)
- (added) llvm/utils/lit/tests/unit/FilterRequires.py (+164)
``````````diff
diff --git a/llvm/docs/CommandGuide/lit.md b/llvm/docs/CommandGuide/lit.md
index f652110bfc2cbb..58b450c01859db 100644
--- a/llvm/docs/CommandGuide/lit.md
+++ b/llvm/docs/CommandGuide/lit.md
@@ -326,6 +326,17 @@ Run only those tests that previously failed. Tests that have been newly added
but not yet run are not included.
:::
+:::{option} --filter-requires EXPR
+Run only those tests with a `REQUIRES` combination matching the requested positive
+features exactly and no extra exclusions. Names are case sensitive and commas mean
+AND. An explicitly empty argument (`--filter-requires=""`) selects only tests with
+no `REQUIRES` entries. Omitting the option disables requirement selection and preserves
+normal `REQUIRES` availability checks. Matching tests bypass `REQUIRES` availability
+checks. `UNSUPPORTED` and `XFAIL` still apply. Regexes are unsupported. The maximum
+test count applies before requirement matching. The caller must choose a suitable
+device.
+:::
+
:::{option} --xfail LIST
Treat those tests whose name is in the semicolon separated list `LIST` as
`XFAIL`. This can be helpful when one does not want to modify the test
diff --git a/llvm/utils/lit/lit/FilterRequires.py b/llvm/utils/lit/lit/FilterRequires.py
new file mode 100644
index 00000000000000..95fa0aab3c83c0
--- /dev/null
+++ b/llvm/utils/lit/lit/FilterRequires.py
@@ -0,0 +1,138 @@
+from lit.BooleanExpression import BooleanExpression
+
+
+class _Parser(BooleanExpression):
+ """Reuse lit's tokens and grammar, but retain the expression's structure."""
+
+ def parseMATCH(self):
+ if "{{" in self.token:
+ raise ValueError("--filter-requires does not support '{{regex}}' patterns")
+ self.value = ("literal", self.token)
+ self.token = next(self.tokens)
+
+ def parseNOT(self):
+ if self.accept("!"):
+ self.parseNOT()
+ self.value = ("not", self.value)
+ else:
+ super().parseNOT()
+
+ def parseAND(self):
+ self.parseNOT()
+ children = [self.value]
+ while self.accept("&&"):
+ self.parseNOT()
+ children.append(self.value)
+ self.value = ("and", children)
+
+ def parseOR(self):
+ self.parseAND()
+ children = [self.value]
+ while self.accept("||"):
+ self.parseAND()
+ children.append(self.value)
+ self.value = ("or", children)
+
+
+class FilterRequires:
+ """Select tests by their required features, not available features.
+
+ Expressions are expanded into combinations of required and excluded
+ features. A test combination matches a filter combination when their
+ required features are identical and the test adds no extra excluded
+ features. Contradictory combinations are discarded.
+ """
+
+ MAX_COMBINATIONS = 1024
+ MAX_STEPS = 100000
+
+ def __init__(self, expression):
+ self.expression = expression
+ self.selects_no_requirements = expression == ""
+ self.combinations = (
+ None if self.selects_no_requirements else self._normalize([expression])
+ )
+
+ def __str__(self):
+ return self.expression
+
+ @classmethod
+ def _normalize(cls, expressions):
+ steps = 0
+
+ def step():
+ nonlocal steps
+ steps += 1
+ if steps > cls.MAX_STEPS:
+ raise ValueError(
+ "--filter-requires expression exceeds the normalization "
+ "limit (%d steps)" % cls.MAX_STEPS
+ )
+
+ def add(combinations, combination):
+ combinations.add(combination)
+ if len(combinations) > cls.MAX_COMBINATIONS:
+ raise ValueError(
+ "--filter-requires expression exceeds the combination "
+ "limit (%d combinations)" % cls.MAX_COMBINATIONS
+ )
+
+ def combine(left, right):
+ result = set()
+ for lp, ln in left:
+ for rp, rn in right:
+ step()
+ if not (lp & rn or rp & ln):
+ add(result, (lp | rp, ln | rn))
+ return result
+
+ def expand(node, negate=False):
+ step()
+ kind, value = node
+ if kind == "literal":
+ if value == "true":
+ return set() if negate else {empty}
+ literal = frozenset([value])
+ return {(empty[0], literal) if negate else (literal, empty[1])}
+ if kind == "not":
+ return expand(value, not negate)
+ # Push NOT through AND/OR using De Morgan's laws.
+ conjunction = (kind == "and") != negate
+ combinations = {empty} if conjunction else set()
+ for child in value:
+ child_combinations = expand(child, negate)
+ if conjunction:
+ combinations = combine(combinations, child_combinations)
+ else:
+ for combination in child_combinations:
+ step()
+ add(combinations, combination)
+ return combinations
+
+ empty = (frozenset(), frozenset())
+ result = {empty}
+ try:
+ for expression in expressions:
+ # Commas delimit complete expressions, as in REQUIRES lines.
+ for part in expression.split(","):
+ tree = _Parser(part.strip(), set()).parseAll()
+ result = combine(result, expand(tree))
+ except RecursionError:
+ raise ValueError(
+ "--filter-requires expression is nested too deeply"
+ ) from None
+ except ValueError as error:
+ raise ValueError("%s\nin REQUIRES selection: %r" % (error, expression))
+ return result
+
+ def matches(self, requirements):
+ if self.selects_no_requirements:
+ return not requirements
+ if not requirements:
+ return False
+ test_combinations = self._normalize(requirements)
+ return any(
+ test_positive == caller_positive and test_negative <= caller_negative
+ for test_positive, test_negative in test_combinations
+ for caller_positive, caller_negative in self.combinations
+ )
diff --git a/llvm/utils/lit/lit/Test.py b/llvm/utils/lit/lit/Test.py
index 35da7afc591c0e..d80b225a748f56 100644
--- a/llvm/utils/lit/lit/Test.py
+++ b/llvm/utils/lit/lit/Test.py
@@ -271,6 +271,9 @@ def __init__(
# must be True for the test to run.
self.requires = []
+ # Optional requirement matching, independent of available features.
+ self.filter_requires = None
+
# A list of conditions that prevent execution of the test.
# Each condition is a boolean expression of features. All of them
# must be False for the test to run.
diff --git a/llvm/utils/lit/lit/TestRunner.py b/llvm/utils/lit/lit/TestRunner.py
index 9ef299d82c1183..42e7f167ed657c 100644
--- a/llvm/utils/lit/lit/TestRunner.py
+++ b/llvm/utils/lit/lit/TestRunner.py
@@ -2111,6 +2111,10 @@ def parseIntegratedTestScript(test, additional_parsers=[], require_script=True):
If 'require_script' is False an empty script
may be returned. This can be used for test formats where the actual script
is optional or ignored.
+
+ With --filter-requires, select REQUIRES combinations instead of
+ checking their availability. UNSUPPORTED and XFAIL still use the configured
+ available features.
"""
# Parse the test sources and extract test properties
try:
@@ -2130,14 +2134,31 @@ def parseIntegratedTestScript(test, additional_parsers=[], require_script=True):
if parsed["ALLOW_RETRIES:"]:
test.allowed_retries = parsed["ALLOW_RETRIES:"][0]
- # Enforce REQUIRES:
- missing_required_features = test.getMissingRequiredFeatures()
- if missing_required_features:
- msg = ", ".join(missing_required_features)
- return lit.Test.Result(
- Test.UNSUPPORTED,
- "Test requires the following unavailable " "features: %s" % msg,
- )
+ if test.filter_requires is not None:
+ if test.config.limit_to_features:
+ return lit.Test.Result(
+ Test.UNRESOLVED,
+ "--filter-requires cannot be combined with limit_to_features",
+ )
+ try:
+ matches = test.filter_requires.matches(test.requires)
+ except ValueError as error:
+ return lit.Test.Result(Test.UNRESOLVED, str(error))
+ if not matches:
+ return lit.Test.Result(
+ Test.EXCLUDED,
+ "Test REQUIRES does not match --filter-requires %r"
+ % str(test.filter_requires),
+ )
+ else:
+ # Enforce REQUIRES feature availability only without explicit selection.
+ missing_required_features = test.getMissingRequiredFeatures()
+ if missing_required_features:
+ msg = ", ".join(missing_required_features)
+ return lit.Test.Result(
+ Test.UNSUPPORTED,
+ "Test requires the following unavailable " "features: %s" % msg,
+ )
# Enforce UNSUPPORTED:
unsupported_features = test.getUnsupportedFeatures()
diff --git a/llvm/utils/lit/lit/cl_arguments.py b/llvm/utils/lit/lit/cl_arguments.py
index be0f154a105520..cc962eaef371fd 100644
--- a/llvm/utils/lit/lit/cl_arguments.py
+++ b/llvm/utils/lit/lit/cl_arguments.py
@@ -6,6 +6,7 @@
import lit.reports
import lit.util
+import lit.FilterRequires
@enum.unique
@@ -456,6 +457,19 @@ def parse_args():
help="Filter out tests with paths matching the given regular expression",
default=os.environ.get("LIT_FILTER_OUT", "^$"),
)
+ selection_group.add_argument(
+ "--filter-requires",
+ metavar="EXPR",
+ type=_requires_filter,
+ help="Select REQUIRES combinations with exactly the requested "
+ "positive features and no unrequested exclusions. Supports &&, ||, !, "
+ "parentheses, and commas (AND), not regexes or wildcards. Feature names "
+ 'are case-sensitive. --filter-requires="" selects tests with no REQUIRES '
+ "entries. "
+ "Bypasses REQUIRES feature availability checks; "
+ "the caller must schedule on capable devices. Nonmatching tests are "
+ "excluded. WTT reports also omit unsupported tests in filtered runs.",
+ )
selection_group.add_argument(
"--filter-failed",
dest="filterFailed",
@@ -646,6 +660,13 @@ def _float(arg, kind, pred):
return f
+def _requires_filter(arg):
+ try:
+ return lit.FilterRequires.FilterRequires(arg)
+ except ValueError as error:
+ raise argparse.ArgumentTypeError(str(error))
+
+
def _case_insensitive_regex(arg):
import re
diff --git a/llvm/utils/lit/lit/main.py b/llvm/utils/lit/lit/main.py
index 801bdf6808d521..83e458b6cab559 100755
--- a/llvm/utils/lit/lit/main.py
+++ b/llvm/utils/lit/lit/main.py
@@ -114,6 +114,9 @@ def main(builtin_params={}):
mark_xfail(discovered_tests, opts)
mark_unsupported(discovered_tests, opts)
+ for test in selected_tests:
+ test.filter_requires = opts.filter_requires
+
mark_excluded(discovered_tests, selected_tests)
start = time.time()
diff --git a/llvm/utils/lit/lit/reports.py b/llvm/utils/lit/lit/reports.py
index c2ab010d1ae93a..9b35e74b4c9d52 100755
--- a/llvm/utils/lit/lit/reports.py
+++ b/llvm/utils/lit/lit/reports.py
@@ -363,6 +363,7 @@ def rc(ref_ctx: str) -> str:
passed = 0
failed = 0
unsupported = 0
+ unsupported_not_run = 0
excluded = 0
skipped = 0
@@ -376,6 +377,9 @@ def rc(ref_ctx: str) -> str:
# UNSUPPORTED: report as Pass (feature not applicable on this device).
if code == lit.Test.UNSUPPORTED:
+ if test.filter_requires is not None:
+ unsupported_not_run += 1
+ continue
file.write(f'<CTX ID="" Current={_wtt_attr(name)} Parent="WTTLOG" />\n')
file.write(
f'<StartTest Title={_wtt_attr(name)} TUID="" CA="{created_at}" LA="{created_at}">\n{rc("")}</StartTest>\n'
@@ -440,13 +444,15 @@ def rc(ref_ctx: str) -> str:
)
# Tally of tests omitted from results.
- not_run = excluded + skipped
+ not_run = excluded + skipped + unsupported_not_run
if not_run > 0:
parts = []
if excluded:
parts.append(f"{excluded} excluded")
if skipped:
parts.append(f"{skipped} skipped")
+ if unsupported_not_run:
+ parts.append(f"{unsupported_not_run} unsupported")
tally = _wtt_attr(
f"{not_run} test(s) were not run ({', '.join(parts)}) and are "
f"omitted from the pass/fail results."
diff --git a/llvm/utils/lit/tests/Inputs/filter-requires/and.txt b/llvm/utils/lit/tests/Inputs/filter-requires/and.txt
new file mode 100644
index 00000000000000..296ac6e717ea79
--- /dev/null
+++ b/llvm/utils/lit/tests/Inputs/filter-requires/and.txt
@@ -0,0 +1,3 @@
+# REQUIRES: Half, true
+# REQUIRES: Int16
+# RUN: echo and
diff --git a/llvm/utils/lit/tests/Inputs/filter-requires/features.txt b/llvm/utils/lit/tests/Inputs/filter-requires/features.txt
new file mode 100644
index 00000000000000..16158354275f74
--- /dev/null
+++ b/llvm/utils/lit/tests/Inputs/filter-requires/features.txt
@@ -0,0 +1,5 @@
+# REQUIRES: Half
+# UNSUPPORTED: Half
+# XFAIL: Half
+# RUN: %if host %{ echo host still present %} %else %{ false %}
+# RUN: %if Half %{ false %} %else %{ echo Half still absent %}
diff --git a/llvm/utils/lit/tests/Inputs/filter-requires/half.txt b/llvm/utils/lit/tests/Inputs/filter-requires/half.txt
new file mode 100644
index 00000000000000..c887aaf22d06bf
--- /dev/null
+++ b/llvm/utils/lit/tests/Inputs/filter-requires/half.txt
@@ -0,0 +1,2 @@
+# REQUIRES: Half
+# RUN: echo half
diff --git a/llvm/utils/lit/tests/Inputs/filter-requires/lit.cfg b/llvm/utils/lit/tests/Inputs/filter-requires/lit.cfg
new file mode 100644
index 00000000000000..54b202baf011bc
--- /dev/null
+++ b/llvm/utils/lit/tests/Inputs/filter-requires/lit.cfg
@@ -0,0 +1,10 @@
+import lit.formats
+
+config.name = "filter-requires"
+config.suffixes = [".txt"]
+config.test_format = lit.formats.ShTest()
+config.test_source_root = None
+config.test_exec_root = None
+config.available_features = {"host"}
+if lit_config.params.get("limit"):
+ config.limit_to_features = ["Half"]
diff --git a/llvm/utils/lit/tests/Inputs/filter-requires/negative.txt b/llvm/utils/lit/tests/Inputs/filter-requires/negative.txt
new file mode 100644
index 00000000000000..b3225037965867
--- /dev/null
+++ b/llvm/utils/lit/tests/Inputs/filter-requires/negative.txt
@@ -0,0 +1,2 @@
+# REQUIRES: Half && !Double
+# RUN: echo negative
diff --git a/llvm/utils/lit/tests/Inputs/filter-requires/nested.txt b/llvm/utils/lit/tests/Inputs/filter-requires/nested.txt
new file mode 100644
index 00000000000000..1d7bb81b4b326f
--- /dev/null
+++ b/llvm/utils/lit/tests/Inputs/filter-requires/nested.txt
@@ -0,0 +1,3 @@
+# REQUIRES: Half && \
+# REQUIRES: (Int16 || Double)
+# RUN: echo nested
diff --git a/llvm/utils/lit/tests/Inputs/filter-requires/no-requires.txt b/llvm/utils/lit/tests/Inputs/filter-requires/no-requires.txt
new file mode 100644
index 00000000000000..9d7149623587f0
--- /dev/null
+++ b/llvm/utils/lit/tests/Inputs/filter-requires/no-requires.txt
@@ -0,0 +1 @@
+# RUN: echo no requirements
diff --git a/llvm/utils/lit/tests/Inputs/filter-requires/or.txt b/llvm/utils/lit/tests/Inputs/filter-requires/or.txt
new file mode 100644
index 00000000000000..9b6003ea1e6abd
--- /dev/null
+++ b/llvm/utils/lit/tests/Inputs/filter-requires/or.txt
@@ -0,0 +1,2 @@
+# REQUIRES: Half || Int16
+# RUN: echo or
diff --git a/llvm/utils/lit/tests/Inputs/filter-requires/regex.txt b/llvm/utils/lit/tests/Inputs/filter-requires/regex.txt
new file mode 100644
index 00000000000000..438bad25755100
--- /dev/null
+++ b/llvm/utils/lit/tests/Inputs/filter-requires/regex.txt
@@ -0,0 +1,2 @@
+# REQUIRES: {{host.*}}
+# RUN: echo regex
diff --git a/llvm/utils/lit/tests/Inputs/filter-requires/true.txt b/llvm/utils/lit/tests/Inputs/filter-requires/true.txt
new file mode 100644
index 00000000000000..bce0d49067e8e1
--- /dev/null
+++ b/llvm/utils/lit/tests/Inputs/filter-requires/true.txt
@@ -0,0 +1,2 @@
+# REQUIRES: true
+# RUN: echo true
diff --git a/llvm/utils/lit/tests/Inputs/filter-requires/unsupported.txt b/llvm/utils/lit/tests/Inputs/filter-requires/unsupported.txt
new file mode 100644
index 00000000000000..44cd3956281a39
--- /dev/null
+++ b/llvm/utils/lit/tests/Inputs/filter-requires/unsupported.txt
@@ -0,0 +1,3 @@
+# REQUIRES: Half
+# UNSUPPORTED: host
+# RUN: echo must not execute
diff --git a/llvm/utils/lit/tests/Inputs/filter-requires/xfail.txt b/llvm/utils/lit/tests/Inputs/filter-requires/xfail.txt
new file mode 100644
index 00000000000000..b92928ea3df3a4
--- /dev/null
+++ b/llvm/utils/lit/tests/Inputs/filter-requires/xfail.txt
@@ -0,0 +1,3 @@
+# REQUIRES: Half
+# XFAIL: host
+# RUN: false
diff --git a/llvm/utils/lit/tests/filter-requires-selection.py b/llvm/utils/lit/tests/filter-requires-selection.py
new file mode 100644
index 00000000000000..bf2b759a61156d
--- /dev/null
+++ b/llvm/utils/lit/tests/filter-requires-selection.py
@@ -0,0 +1,92 @@
+# RUN: %{lit} -a --filter-requires=Half --filter-out=regex %S/Inputs/filter-requires | FileCheck %s --check-prefix=HALF
+# HALF: EXCLUDED{{:}} filter-requires :: and.txt
+# HALF: PASS: filter-requires :: features.txt
+# HALF: PASS: filter-requires :: half.txt
+# HALF: EXCLUDED{{:}} filter-requires :: negative.txt
+# HALF: EXCLUDED{{:}} filter-requires :: nested.txt
+# HALF: EXCLUDED{{:}} filter-requires :: no-requires.txt
+# HALF: PASS: filter-requires :: or.txt
+# HALF: EXCLUDED{{:}} filter-requires :: true.txt
+# HALF: UNSUPPORTED{{:}} filter-requires :: unsupported.txt
+# HALF: XFAIL{{:}} filter-requires :: xfail.txt
+
+# RUN: %{lit} -a --filter-requires="Int16, Half" --filter-out=regex %S/Inputs/filter-requires | FileCheck %s --check-prefix=AND
+# AND: PASS: filter-requires :: and.txt
+# AND: EXCLUDED{{:}} filter-requires :: half.txt
+# AND: PASS: filter-requires :: nested.txt
+# AND: EXCLUDED{{:}} filter-requires :: or.txt
+
+# RUN: %{lit} -a --filter-requires="Half || Int16" --filter-out=regex %S/Inputs/filter-requires | FileCheck %s --check-prefix=OR
+# OR: EXCLUDED{{:}} filter-requires :: and.txt
+# OR: PASS: filter-requires :: half.txt
+# OR: EXCLUDED{{:}} filter-requires :: nested.txt
+# OR: PASS: filter-requires :: or.txt
+
+# RUN: %{lit} -a --filter-requires="Half && !Double" --filter-out=regex %S/Inputs/filter-requires | FileCheck %s --check-prefix=NEGATIVE
+# NEGATIVE: PASS: filter-requires :: half.txt
+# NEGATIVE: PASS: filter-requires :: negative.txt
+# NEGATIVE: EXCLUDED{{:}} filter-requires :: nested.txt
+
+# RUN: %{lit} -a --filter-requires="Half && Int16 && !Double" --filter-out=regex %S/Inputs/filter-requires | FileCheck %s --check-prefix=NESTED
+# NESTED: PASS: filter-requires :: and.txt
+# NESTED: EXCLUDED{{:}} filter-requires :: half.txt
+# NESTED: PASS: filter-requires :: nested.txt
+# NESTED: EXCLUDED{{:}} filter-requires :: or.txt
+
+# RUN: %{lit} -a --filter-requires="" %S/Inputs/filter-requires | FileCheck %s --check-prefix=NO-REQS
+# NO-REQS: EXCLUDED{{:}} filter-requires :: half.txt
+# NO-REQS: PASS: filter-requires :: no-requires.txt
+# NO-REQS: EXCLUDED{{:}} filter-requires :: true.txt
+# NO-REQS: Passed{{ *}}: 1
+
+# RUN: %{lit} -a --filter-requires=true --filter-out=regex %S/Inputs/filter-requires | FileCheck %s --check-prefix=TRUE
+# TRUE: EXCLUDED{{:}} filter-requires :: half.txt
+# TRUE: EXCLUDED{{:}} filter-requires :: no-requires.txt
+# TRUE: PASS: filter-requires :: true.txt
+# TRUE: Passed{{ *}}: 1
+
+# RUN: %{lit} -a %S/Inputs/filter-requires | FileCheck %s --check-prefix=DEFAULT
+# DEFAULT: UNSUPPORTED{{:}} filter-requires :...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/221873
More information about the llvm-commits
mailing list