Skip to content

Add LIT_UNSUPPORTED support to lit testing#193766

Open
lei137 wants to merge 1 commit intollvm:mainfrom
lei137:litUnsupported
Open

Add LIT_UNSUPPORTED support to lit testing#193766
lei137 wants to merge 1 commit intollvm:mainfrom
lei137:litUnsupported

Conversation

@lei137
Copy link
Copy Markdown
Contributor

@lei137 lei137 commented Apr 23, 2026

Add LIT_UNSUPPORTED support to lit, mirroring the existing LIT_XFAIL
implementation. This allows tests to be marked as UNSUPPORTED via
command line arguments (--unsupported, --unsupported-not) or environment
variables (LIT_UNSUPPORTED, LIT_UNSUPPORTED_NOT).

This feature enables users to dynamically mark tests as unsupported
without modifying test files, useful for CI/CD pipelines and
platform-specific test filtering.

Assisted by AI.

Add LIT_UNSUPPORTED support to lit, mirroring the existing LIT_XFAIL
implementation. This allows tests to be marked as UNSUPPORTED via
command line arguments (--unsupported, --unsupported-not) or environment
variables (LIT_UNSUPPORTED, LIT_UNSUPPORTED_NOT).

This feature enables users to dynamically mark tests as unsupported
without modifying test files, useful for CI/CD pipelines and
platform-specific test filtering.

Assisted by AI.
@llvmbot
Copy link
Copy Markdown
Member

llvmbot commented Apr 23, 2026

@llvm/pr-subscribers-testing-tools

Author: Lei Huang (lei137)

Changes

Add LIT_UNSUPPORTED support to lit, mirroring the existing LIT_XFAIL
implementation. This allows tests to be marked as UNSUPPORTED via
command line arguments (--unsupported, --unsupported-not) or environment
variables (LIT_UNSUPPORTED, LIT_UNSUPPORTED_NOT).

This feature enables users to dynamically mark tests as unsupported
without modifying test files, useful for CI/CD pipelines and
platform-specific test filtering.

Assisted by AI.


Full diff: https://github.com/llvm/llvm-project/pull/193766.diff

4 Files Affected:

  • (modified) llvm/utils/lit/lit/Test.py (+6)
  • (modified) llvm/utils/lit/lit/cl_arguments.py (+14)
  • (modified) llvm/utils/lit/lit/main.py (+13)
  • (added) llvm/utils/lit/tests/unsupported-cl.py (+39)
diff --git a/llvm/utils/lit/lit/Test.py b/llvm/utils/lit/lit/Test.py
index daba14a898c4c..6f87ecfc82d15 100644
--- a/llvm/utils/lit/lit/Test.py
+++ b/llvm/utils/lit/lit/Test.py
@@ -262,6 +262,9 @@ def __init__(
         # If true, ignore all items in self.xfails.
         self.xfail_not = False
 
+        # If true, ignore all items in self.unsupported.
+        self.unsupported_not = False
+
         # A list of conditions that must be satisfied before running the test.
         # Each condition is a boolean expression of features. All of them
         # must be True for the test to run.
@@ -423,6 +426,9 @@ def getUnsupportedFeatures(self):
         Throws ValueError if an UNSUPPORTED line has a syntax error.
         """
 
+        if self.unsupported_not:
+            return []
+
         features = self.config.available_features
 
         try:
diff --git a/llvm/utils/lit/lit/cl_arguments.py b/llvm/utils/lit/lit/cl_arguments.py
index bebde4b762b0e..a2e1d51e7bc83 100644
--- a/llvm/utils/lit/lit/cl_arguments.py
+++ b/llvm/utils/lit/lit/cl_arguments.py
@@ -464,6 +464,20 @@ def parse_args():
         default=False,
         action="store_true",
     )
+    selection_group.add_argument(
+        "--unsupported",
+        metavar="LIST",
+        type=_semicolon_list,
+        help="UNSUPPORTED tests with paths in the semicolon separated list",
+        default=os.environ.get("LIT_UNSUPPORTED", ""),
+    )
+    selection_group.add_argument(
+        "--unsupported-not",
+        metavar="LIST",
+        type=_semicolon_list,
+        help="do not UNSUPPORTED tests with paths in the semicolon separated list",
+        default=os.environ.get("LIT_UNSUPPORTED_NOT", ""),
+    )
     selection_group.add_argument(
         "--num-shards",
         dest="numShards",
diff --git a/llvm/utils/lit/lit/main.py b/llvm/utils/lit/lit/main.py
index 77b23bf560c6e..4f07cb30b4e5b 100755
--- a/llvm/utils/lit/lit/main.py
+++ b/llvm/utils/lit/lit/main.py
@@ -122,6 +122,7 @@ def main(builtin_params={}):
     selected_tests = selected_tests[: opts.max_tests]
 
     mark_xfail(discovered_tests, opts)
+    mark_unsupported(discovered_tests, opts)
 
     mark_excluded(discovered_tests, selected_tests)
 
@@ -248,6 +249,18 @@ def mark_xfail(selected_tests, opts):
             t.exclude_xfail = True
 
 
+def mark_unsupported(selected_tests, opts):
+    for t in selected_tests:
+        test_file = os.sep.join(t.path_in_suite)
+        test_full_name = t.getFullName()
+        if test_file in opts.unsupported or test_full_name in opts.unsupported:
+            # Add a special feature that's always present to mark as unsupported
+            t.config.available_features.add("lit-unsupported-marker")
+            t.unsupported.append("lit-unsupported-marker")
+        if test_file in opts.unsupported_not or test_full_name in opts.unsupported_not:
+            t.unsupported_not = True
+
+
 def mark_excluded(discovered_tests, selected_tests):
     excluded_tests = set(discovered_tests) - set(selected_tests)
     result = lit.Test.Result(lit.Test.EXCLUDED)
diff --git a/llvm/utils/lit/tests/unsupported-cl.py b/llvm/utils/lit/tests/unsupported-cl.py
new file mode 100644
index 0000000000000..b654cbccd1abe
--- /dev/null
+++ b/llvm/utils/lit/tests/unsupported-cl.py
@@ -0,0 +1,39 @@
+# Check that marking tests as UNSUPPORTED works via command line or env var.
+
+# RUN: %{lit} --unsupported 'false.txt;false2.txt;top-level-suite :: b :: test.txt' \
+# RUN:   --unsupported-not 'true-xfail.txt;top-level-suite :: a :: test-xfail.txt' \
+# RUN:   %{inputs}/xfail-cl \
+# RUN: | FileCheck --check-prefix=CHECK-FILTER %s
+
+# RUN: env LIT_UNSUPPORTED='false.txt;false2.txt;top-level-suite :: b :: test.txt' \
+# RUN:   LIT_UNSUPPORTED_NOT='true-xfail.txt;top-level-suite :: a :: test-xfail.txt' \
+# RUN: %{lit} %{inputs}/xfail-cl \
+# RUN: | FileCheck --check-prefix=CHECK-FILTER %s
+
+# Check that --unsupported-not and LIT_UNSUPPORTED_NOT always have precedence.
+
+# RUN: env LIT_UNSUPPORTED=true-xfail.txt \
+# RUN: %{lit} --unsupported true-xfail.txt --unsupported-not true-xfail.txt \
+# RUN:   --unsupported true-xfail.txt %{inputs}/xfail-cl/true-xfail.txt \
+# RUN: | FileCheck --check-prefix=CHECK-OVERRIDE %s
+
+# RUN: env LIT_UNSUPPORTED_NOT=true-xfail.txt LIT_UNSUPPORTED=true-xfail.txt \
+# RUN: %{lit} --unsupported true-xfail.txt %{inputs}/xfail-cl/true-xfail.txt \
+# RUN: | FileCheck --check-prefix=CHECK-OVERRIDE %s
+
+# END.
+
+# CHECK-FILTER: Testing: 11 tests, {{[0-9]*}} workers
+# CHECK-FILTER-DAG: {{^}}PASS: top-level-suite :: a :: test.txt
+# CHECK-FILTER-DAG: {{^}}UNSUPPORTED: top-level-suite :: b :: test.txt
+# CHECK-FILTER-DAG: {{^}}UNSUPPORTED: top-level-suite :: a :: false.txt
+# CHECK-FILTER-DAG: {{^}}UNSUPPORTED: top-level-suite :: b :: false.txt
+# CHECK-FILTER-DAG: {{^}}UNSUPPORTED: top-level-suite :: false.txt
+# CHECK-FILTER-DAG: {{^}}UNSUPPORTED: top-level-suite :: false2.txt
+# CHECK-FILTER-DAG: {{^}}PASS: top-level-suite :: true.txt
+# CHECK-FILTER-DAG: {{^}}PASS: top-level-suite :: true-xfail.txt
+# CHECK-FILTER-DAG: {{^}}PASS: top-level-suite :: a :: test-xfail.txt
+# CHECK-FILTER-DAG: {{^}}UNSUPPORTED: top-level-suite :: b :: test-xfail.txt
+
+# CHECK-OVERRIDE: Testing: 1 tests, {{[0-9]*}} workers
+# CHECK-OVERRIDE: {{^}}PASS: top-level-suite :: true-xfail.txt

@github-actions
Copy link
Copy Markdown

🐧 Linux x64 Test Results

  • 173243 tests passed
  • 3225 tests skipped
  • 1 test failed

Failed Tests

(click on a test name to see its output)

lit

lit.lit/unsupported-cl.py
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 3
env -u FILECHECK_OPTS "/usr/bin/python3" /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/utils/lit/lit.py -j1 -D use_normalized_slashes=0 --order=lexical --unsupported 'false.txt;false2.txt;top-level-suite :: b :: test.txt'    --unsupported-not 'true-xfail.txt;top-level-suite :: a :: test-xfail.txt'    Inputs/xfail-cl  | FileCheck --check-prefix=CHECK-FILTER /home/gha/actions-runner/_work/llvm-project/llvm-project/build/utils/lit/tests/unsupported-cl.py
# executed command: env -u FILECHECK_OPTS /usr/bin/python3 /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/utils/lit/lit.py -j1 -D use_normalized_slashes=0 --order=lexical --unsupported 'false.txt;false2.txt;top-level-suite :: b :: test.txt' --unsupported-not 'true-xfail.txt;top-level-suite :: a :: test-xfail.txt' Inputs/xfail-cl
# note: command had no output on stdout or stderr
# error: command failed with exit status: 1
# executed command: FileCheck --check-prefix=CHECK-FILTER /home/gha/actions-runner/_work/llvm-project/llvm-project/build/utils/lit/tests/unsupported-cl.py
# .---command stderr------------
# | /home/gha/actions-runner/_work/llvm-project/llvm-project/build/utils/lit/tests/unsupported-cl.py:34:21: error: CHECK-FILTER-DAG: expected string not found in input
# | # CHECK-FILTER-DAG: {{^}}PASS: top-level-suite :: true-xfail.txt
# |                     ^
# | <stdin>:1:32: note: scanning from here
# | -- Testing: 11 tests, 1 workers --
# |                                ^
# | <stdin>:11:1: note: possible intended match here
# | XPASS: top-level-suite :: true-xfail.txt (10 of 11)
# | ^
# | 
# | Input file: <stdin>
# | Check file: /home/gha/actions-runner/_work/llvm-project/llvm-project/build/utils/lit/tests/unsupported-cl.py
# | 
# | -dump-input=help explains the following input dump.
# | 
# | Input was:
# | <<<<<<
# |           1: -- Testing: 11 tests, 1 workers -- 
# | dag:34'0                                    X~~~ error: no match found
# |           2: UNSUPPORTED: top-level-suite :: a :: false.txt (1 of 11) 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |           3: XPASS: top-level-suite :: a :: test-xfail.txt (2 of 11) 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |           4: PASS: top-level-suite :: a :: test.txt (3 of 11) 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |           5: UNSUPPORTED: top-level-suite :: b :: false.txt (4 of 11) 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |           6: XFAIL: top-level-suite :: b :: test-xfail.txt (5 of 11) 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |           7: UNSUPPORTED: top-level-suite :: b :: test.txt (6 of 11) 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |           8: UNSUPPORTED: top-level-suite :: false.txt (7 of 11) 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |           9: UNSUPPORTED: top-level-suite :: false2.txt (8 of 11) 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |          10: PASS: top-level-suite :: true-xfail-conditionally.txt (9 of 11) 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |          11: XPASS: top-level-suite :: true-xfail.txt (10 of 11) 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# | dag:34'1     ?                                                    possible intended match
# |          12: PASS: top-level-suite :: true.txt (11 of 11) 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |          13: ******************** 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~
# |          14: Unexpectedly Passed Tests (2): 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |          15:  top-level-suite :: a :: test-xfail.txt 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |          16:  top-level-suite :: true-xfail.txt 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |           .
# |           .
# |           .
# | >>>>>>
# `-----------------------------
# error: command failed with exit status: 1

--

If these failures are unrelated to your changes (for example tests are broken or flaky at HEAD), please open an issue at https://github.com/llvm/llvm-project/issues and add the infrastructure label.

@github-actions
Copy link
Copy Markdown

🪟 Windows x64 Test Results

  • 133906 tests passed
  • 3148 tests skipped
  • 1 test failed

Failed Tests

(click on a test name to see its output)

lit

lit.lit/unsupported-cl.py
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 3
env -u FILECHECK_OPTS "C:\Python312\python.exe" C:\_work\llvm-project\llvm-project\llvm\utils\lit\lit.py -j1 -D use_normalized_slashes=0 --order=lexical --unsupported 'false.txt;false2.txt;top-level-suite :: b :: test.txt'    --unsupported-not 'true-xfail.txt;top-level-suite :: a :: test-xfail.txt'    Inputs/xfail-cl  | FileCheck --check-prefix=CHECK-FILTER C:\_work\llvm-project\llvm-project\build\utils\lit\tests\unsupported-cl.py
# executed command: env -u FILECHECK_OPTS 'C:\Python312\python.exe' 'C:\_work\llvm-project\llvm-project\llvm\utils\lit\lit.py' -j1 -D use_normalized_slashes=0 --order=lexical --unsupported 'false.txt;false2.txt;top-level-suite :: b :: test.txt' --unsupported-not 'true-xfail.txt;top-level-suite :: a :: test-xfail.txt' Inputs/xfail-cl
# note: command had no output on stdout or stderr
# error: command failed with exit status: 1
# executed command: FileCheck --check-prefix=CHECK-FILTER 'C:\_work\llvm-project\llvm-project\build\utils\lit\tests\unsupported-cl.py'
# .---command stderr------------
# | C:\_work\llvm-project\llvm-project\build\utils\lit\tests\unsupported-cl.py:34:21: error: CHECK-FILTER-DAG: expected string not found in input
# | # CHECK-FILTER-DAG: {{^}}PASS: top-level-suite :: true-xfail.txt
# |                     ^
# | <stdin>:1:32: note: scanning from here
# | -- Testing: 11 tests, 1 workers --
# |                                ^
# | <stdin>:11:1: note: possible intended match here
# | XPASS: top-level-suite :: true-xfail.txt (10 of 11)
# | ^
# | 
# | Input file: <stdin>
# | Check file: C:\_work\llvm-project\llvm-project\build\utils\lit\tests\unsupported-cl.py
# | 
# | -dump-input=help explains the following input dump.
# | 
# | Input was:
# | <<<<<<
# |           1: -- Testing: 11 tests, 1 workers -- 
# | dag:34'0                                    X~~~ error: no match found
# |           2: UNSUPPORTED: top-level-suite :: a :: false.txt (1 of 11) 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |           3: XPASS: top-level-suite :: a :: test-xfail.txt (2 of 11) 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |           4: PASS: top-level-suite :: a :: test.txt (3 of 11) 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |           5: UNSUPPORTED: top-level-suite :: b :: false.txt (4 of 11) 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |           6: XFAIL: top-level-suite :: b :: test-xfail.txt (5 of 11) 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |           7: UNSUPPORTED: top-level-suite :: b :: test.txt (6 of 11) 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |           8: UNSUPPORTED: top-level-suite :: false.txt (7 of 11) 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |           9: UNSUPPORTED: top-level-suite :: false2.txt (8 of 11) 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |          10: PASS: top-level-suite :: true-xfail-conditionally.txt (9 of 11) 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |          11: XPASS: top-level-suite :: true-xfail.txt (10 of 11) 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# | dag:34'1     ?                                                    possible intended match
# |          12: PASS: top-level-suite :: true.txt (11 of 11) 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |          13: ******************** 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~
# |          14: Unexpectedly Passed Tests (2): 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |          15:  top-level-suite :: a :: test-xfail.txt 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |          16:  top-level-suite :: true-xfail.txt 
# | dag:34'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |           .
# |           .
# |           .
# | >>>>>>
# `-----------------------------
# error: command failed with exit status: 1

--

If these failures are unrelated to your changes (for example tests are broken or flaky at HEAD), please open an issue at https://github.com/llvm/llvm-project/issues and add the infrastructure label.

@lei137 lei137 requested a review from daltenty April 23, 2026 18:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants