[llvm] Introduce a new CMake option to test LLVM_WINDOWS_PREFER_FORWARD_SLASH behaviors (PR #207194)
Junji Watanabe via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 2 07:26:21 PDT 2026
https://github.com/Jwata created https://github.com/llvm/llvm-project/pull/207194
This PR introduces LLVM_TEST_WINDOWS_PREFER_FORWARD_SLASH_MATRIX which selectively enables tests with both LLVM_WINDOWS_PREFER_FORWARD_SLASH=1 and LLVM_WINDOWS_PREFER_FORWARD_SLASH=0.
>From 16db7ded36d08aa8799ec1484f9ff599b0f44a04 Mon Sep 17 00:00:00 2001
From: Junji Watanabe <jwata at google.com>
Date: Thu, 25 Jun 2026 17:03:19 +0900
Subject: [PATCH 1/2] Implement lit matrix testing for Windows path preferences
- Add LLVM_TEST_WINDOWS_PREFER_FORWARD_SLASH_MATRIX CMake option to support testing both backslash and forward-slash styles in a single lit invocation.
- Vary GTest configuration names in matrix mode to prevent JSON shard report collisions.
---
llvm/CMakeLists.txt | 1 +
llvm/test/CMakeLists.txt | 107 +++++++++++++++++++++++-------
llvm/test/Unit/lit.cfg.py | 16 ++++-
llvm/test/Unit/lit.site.cfg.py.in | 2 +
llvm/test/lit.cfg.py | 15 ++++-
llvm/test/lit.site.cfg.py.in | 2 +
6 files changed, 115 insertions(+), 28 deletions(-)
diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
index cec5462ae02a1..e660db7d6ec83 100644
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -643,6 +643,7 @@ if (MINGW)
set(WINDOWS_PREFER_FORWARD_SLASH_DEFAULT ON)
endif()
option(LLVM_WINDOWS_PREFER_FORWARD_SLASH "Prefer path names with forward slashes on Windows." ${WINDOWS_PREFER_FORWARD_SLASH_DEFAULT})
+option(LLVM_TEST_WINDOWS_PREFER_FORWARD_SLASH_MATRIX "Test both forward and backward slashes on Windows during testing." OFF)
option(LLVM_ENABLE_FFI "Use libffi to call external functions from the interpreter" OFF)
set(FFI_LIBRARY_DIR "" CACHE PATH "Additional directory, where CMake should search for libffi.so")
diff --git a/llvm/test/CMakeLists.txt b/llvm/test/CMakeLists.txt
index 201f0ee86d7ff..ad3a0be993afc 100644
--- a/llvm/test/CMakeLists.txt
+++ b/llvm/test/CMakeLists.txt
@@ -34,30 +34,89 @@ llvm_canonicalize_cmake_booleans(
LLVM_HAVE_OPENCSD
)
-configure_lit_site_cfg(
- ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
- ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py
- MAIN_CONFIG
- ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py
- PATHS
- "CMAKE_OSX_SYSROOT"
- "LLVM_SOURCE_DIR"
- "LLVM_BINARY_DIR"
- "LLVM_TOOLS_DIR"
- "LLVM_LIBS_DIR"
- "SHLIBDIR"
- )
-configure_lit_site_cfg(
- ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.py.in
- ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg.py
- MAIN_CONFIG
- ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.cfg.py
- PATHS
- "LLVM_SOURCE_DIR"
- "LLVM_BINARY_DIR"
- "LLVM_TOOLS_DIR"
- "SHLIBDIR"
- )
+if (LLVM_TEST_WINDOWS_PREFER_FORWARD_SLASH_MATRIX)
+ # Configure unit tests matrix
+ set(LLVM_WINDOWS_PREFER_FORWARD_SLASH_VAL "0")
+ configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.py.in
+ ${CMAKE_CURRENT_BINARY_DIR}/Unit/default/lit.site.cfg.py
+ MAIN_CONFIG
+ ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.cfg.py
+ PATHS
+ "LLVM_SOURCE_DIR"
+ "LLVM_BINARY_DIR"
+ "LLVM_TOOLS_DIR"
+ "SHLIBDIR"
+ )
+ set(LLVM_WINDOWS_PREFER_FORWARD_SLASH_VAL "1")
+ configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.py.in
+ ${CMAKE_CURRENT_BINARY_DIR}/Unit/forward_slash/lit.site.cfg.py
+ MAIN_CONFIG
+ ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.cfg.py
+ PATHS
+ "LLVM_SOURCE_DIR"
+ "LLVM_BINARY_DIR"
+ "LLVM_TOOLS_DIR"
+ "SHLIBDIR"
+ )
+
+ # Configure integration tests matrix
+ set(LLVM_WINDOWS_PREFER_FORWARD_SLASH_VAL "0")
+ configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
+ ${CMAKE_CURRENT_BINARY_DIR}/default/lit.site.cfg.py
+ MAIN_CONFIG
+ ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py
+ PATHS
+ "CMAKE_OSX_SYSROOT"
+ "LLVM_SOURCE_DIR"
+ "LLVM_BINARY_DIR"
+ "LLVM_TOOLS_DIR"
+ "LLVM_LIBS_DIR"
+ "SHLIBDIR"
+ )
+ set(LLVM_WINDOWS_PREFER_FORWARD_SLASH_VAL "1")
+ configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
+ ${CMAKE_CURRENT_BINARY_DIR}/forward_slash/lit.site.cfg.py
+ MAIN_CONFIG
+ ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py
+ PATHS
+ "CMAKE_OSX_SYSROOT"
+ "LLVM_SOURCE_DIR"
+ "LLVM_BINARY_DIR"
+ "LLVM_TOOLS_DIR"
+ "LLVM_LIBS_DIR"
+ "SHLIBDIR"
+ )
+else()
+ set(LLVM_WINDOWS_PREFER_FORWARD_SLASH_VAL "")
+ configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
+ ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py
+ MAIN_CONFIG
+ ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py
+ PATHS
+ "CMAKE_OSX_SYSROOT"
+ "LLVM_SOURCE_DIR"
+ "LLVM_BINARY_DIR"
+ "LLVM_TOOLS_DIR"
+ "LLVM_LIBS_DIR"
+ "SHLIBDIR"
+ )
+ configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.py.in
+ ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg.py
+ MAIN_CONFIG
+ ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.cfg.py
+ PATHS
+ "LLVM_SOURCE_DIR"
+ "LLVM_BINARY_DIR"
+ "LLVM_TOOLS_DIR"
+ "SHLIBDIR"
+ )
+endif()
# Set the depends list as a variable so that it can grow conditionally.
# NOTE: Sync the substitutions in test/lit.cfg when adding to this list.
diff --git a/llvm/test/Unit/lit.cfg.py b/llvm/test/Unit/lit.cfg.py
index e29fd76bd8dcc..307bd7917bf29 100644
--- a/llvm/test/Unit/lit.cfg.py
+++ b/llvm/test/Unit/lit.cfg.py
@@ -8,7 +8,11 @@
import lit.formats
# name: The name of this test suite.
-config.name = "LLVM-Unit"
+suffix = getattr(config, "llvm_windows_prefer_forward_slash", "")
+if suffix in ("1", "ON", "True"):
+ config.name = "LLVM-Unit-ForwardSlash"
+else:
+ config.name = "LLVM-Unit"
# suffixes: A list of file extensions to treat as test files.
config.suffixes = []
@@ -37,6 +41,16 @@
if "HOME" in os.environ:
config.environment["HOME"] = os.environ["HOME"]
+prefer_forward_slash = getattr(config, "llvm_windows_prefer_forward_slash", "")
+if prefer_forward_slash in ("1", "ON", "True"):
+ config.environment["LLVM_WINDOWS_PREFER_FORWARD_SLASH"] = "1"
+elif prefer_forward_slash in ("0", "OFF", "False"):
+ config.environment["LLVM_WINDOWS_PREFER_FORWARD_SLASH"] = "0"
+elif "LLVM_WINDOWS_PREFER_FORWARD_SLASH" in os.environ:
+ config.environment["LLVM_WINDOWS_PREFER_FORWARD_SLASH"] = os.environ[
+ "LLVM_WINDOWS_PREFER_FORWARD_SLASH"
+ ]
+
# Propagate sanitizer options.
for var in [
"ASAN_SYMBOLIZER_PATH",
diff --git a/llvm/test/Unit/lit.site.cfg.py.in b/llvm/test/Unit/lit.site.cfg.py.in
index 3536a34f796a2..bffec61b5b626 100644
--- a/llvm/test/Unit/lit.site.cfg.py.in
+++ b/llvm/test/Unit/lit.site.cfg.py.in
@@ -9,6 +9,8 @@ config.llvm_build_mode = lit_config.substitute("@LLVM_BUILD_MODE@")
config.shlibdir = lit_config.substitute(path(r"@SHLIBDIR@"))
config.gtest_run_under = lit_config.substitute(r"@LLVM_GTEST_RUN_UNDER@")
+config.llvm_windows_prefer_forward_slash = "@LLVM_WINDOWS_PREFER_FORWARD_SLASH_VAL@"
+
# Let the main config do the real work.
lit_config.load_config(
config, os.path.join(config.llvm_src_root, "test/Unit/lit.cfg.py"))
diff --git a/llvm/test/lit.cfg.py b/llvm/test/lit.cfg.py
index 09df1e3fd6281..2662566741d8d 100644
--- a/llvm/test/lit.cfg.py
+++ b/llvm/test/lit.cfg.py
@@ -15,7 +15,11 @@
from lit.llvm.subst import ToolSubst
# name: The name of this test suite.
-config.name = "LLVM"
+suffix = getattr(config, "llvm_windows_prefer_forward_slash", "")
+if suffix in ("1", "ON", "True"):
+ config.name = "LLVM-ForwardSlash"
+else:
+ config.name = "LLVM"
# TODO: Consolidate the logic for turning on the internal shell by default for all LLVM test suites.
# See https://github.com/llvm/llvm-project/issues/106636 for more details.
@@ -102,8 +106,13 @@
# Tweak the PATH to include the tools dir.
llvm_config.with_environment("PATH", config.llvm_tools_dir, append_path=True)
-# Propagate some variables from the host environment.
-llvm_config.with_system_environment(["HOME", "INCLUDE", "LIB", "TMP", "TEMP"])
+llvm_config.with_system_environment(["HOME", "INCLUDE", "LIB", "TMP", "TEMP", "LLVM_WINDOWS_PREFER_FORWARD_SLASH"])
+
+prefer_forward_slash = getattr(config, "llvm_windows_prefer_forward_slash", "")
+if prefer_forward_slash in ("1", "ON", "True"):
+ config.environment["LLVM_WINDOWS_PREFER_FORWARD_SLASH"] = "1"
+elif prefer_forward_slash in ("0", "OFF", "False"):
+ config.environment["LLVM_WINDOWS_PREFER_FORWARD_SLASH"] = "0"
# Set up OCAMLPATH to include newly built OCaml libraries.
diff --git a/llvm/test/lit.site.cfg.py.in b/llvm/test/lit.site.cfg.py.in
index 64679c2f64034..77919ae20068d 100644
--- a/llvm/test/lit.site.cfg.py.in
+++ b/llvm/test/lit.site.cfg.py.in
@@ -74,6 +74,8 @@ config.have_opencsd = @LLVM_HAVE_OPENCSD@
import lit.llvm
lit.llvm.initialize(lit_config, config)
+config.llvm_windows_prefer_forward_slash = "@LLVM_WINDOWS_PREFER_FORWARD_SLASH_VAL@"
+
# Let the main config do the real work.
lit_config.load_config(
config, os.path.join(config.llvm_src_root, "test/lit.cfg.py"))
>From 7c4cdb46176d60c2930432c841951710f81a85fc Mon Sep 17 00:00:00 2001
From: Junji Watanabe <jwata at google.com>
Date: Thu, 2 Jul 2026 23:12:55 +0900
Subject: [PATCH 2/2] Improve lit matrix testing stability and speed on Windows
---
llvm/CMakeLists.txt | 1 +
llvm/test/CMakeLists.txt | 13 ++++++++++++-
llvm/test/Unit/CMakeLists.txt | 13 ++++++++++++-
llvm/test/lit.cfg.py | 16 +++++++++++++++-
llvm/utils/lit/lit/TestRunner.py | 4 +++-
5 files changed, 43 insertions(+), 4 deletions(-)
diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
index c2752e2b73c1d..4bb4492211df2 100644
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -652,6 +652,7 @@ endif()
option(LLVM_WINDOWS_PREFER_FORWARD_SLASH "Prefer path names with forward slashes on Windows." ${WINDOWS_PREFER_FORWARD_SLASH_DEFAULT})
option(LLVM_TEST_WINDOWS_PREFER_FORWARD_SLASH_MATRIX "Test both forward and backward slashes on Windows during testing." OFF)
+
option(LLVM_ENABLE_FFI "Use libffi to call external functions from the interpreter" OFF)
set(FFI_LIBRARY_DIR "" CACHE PATH "Additional directory, where CMake should search for libffi.so")
set(FFI_INCLUDE_DIR "" CACHE PATH "Additional directory, where CMake should search for ffi.h or ffi/ffi.h")
diff --git a/llvm/test/CMakeLists.txt b/llvm/test/CMakeLists.txt
index ad3a0be993afc..fefaf74b88f6c 100644
--- a/llvm/test/CMakeLists.txt
+++ b/llvm/test/CMakeLists.txt
@@ -323,8 +323,19 @@ else()
set(exclude_from_check_all "EXCLUDE_FROM_CHECK_ALL")
endif()
+if (LLVM_TEST_WINDOWS_PREFER_FORWARD_SLASH_MATRIX)
+ set(LLVM_TEST_PATHS
+ ${CMAKE_CURRENT_BINARY_DIR}/default
+ ${CMAKE_CURRENT_BINARY_DIR}/forward_slash
+ )
+else()
+ set(LLVM_TEST_PATHS
+ ${CMAKE_CURRENT_BINARY_DIR}
+ )
+endif()
+
add_lit_testsuite(check-llvm "Running the LLVM regression tests"
- ${CMAKE_CURRENT_BINARY_DIR}
+ ${LLVM_TEST_PATHS}
${exclude_from_check_all}
DEPENDS ${LLVM_TEST_DEPENDS} UnitTests
)
diff --git a/llvm/test/Unit/CMakeLists.txt b/llvm/test/Unit/CMakeLists.txt
index 6b0abe199673f..01e97b6d45c8e 100644
--- a/llvm/test/Unit/CMakeLists.txt
+++ b/llvm/test/Unit/CMakeLists.txt
@@ -1,5 +1,16 @@
+if (LLVM_TEST_WINDOWS_PREFER_FORWARD_SLASH_MATRIX)
+ set(LLVM_UNIT_TEST_PATHS
+ ${CMAKE_CURRENT_BINARY_DIR}/default
+ ${CMAKE_CURRENT_BINARY_DIR}/forward_slash
+ )
+else()
+ set(LLVM_UNIT_TEST_PATHS
+ ${CMAKE_CURRENT_BINARY_DIR}
+ )
+endif()
+
add_lit_testsuite(check-llvm-unit "Running lit suite for LLVM unit tests"
- ${CMAKE_CURRENT_BINARY_DIR}
+ ${LLVM_UNIT_TEST_PATHS}
EXCLUDE_FROM_CHECK_ALL
DEPENDS UnitTests
)
diff --git a/llvm/test/lit.cfg.py b/llvm/test/lit.cfg.py
index 0fc0359d520c3..df2e8ccc50fea 100644
--- a/llvm/test/lit.cfg.py
+++ b/llvm/test/lit.cfg.py
@@ -101,7 +101,13 @@
config.test_source_root = os.path.dirname(__file__)
# test_exec_root: The root path where tests should be run.
-config.test_exec_root = os.path.join(config.llvm_obj_root, "test")
+prefer_forward_slash = getattr(config, "llvm_windows_prefer_forward_slash", "")
+if prefer_forward_slash != "":
+ # In matrix mode, test_exec_root is already set by the site config
+ # loading path, e.g. build_all/test/default or build_all/test/forward_slash.
+ pass
+else:
+ config.test_exec_root = os.path.join(config.llvm_obj_root, "test")
# Tweak the PATH to include the tools dir.
llvm_config.with_environment("PATH", config.llvm_tools_dir, append_path=True)
@@ -111,6 +117,14 @@
prefer_forward_slash = getattr(config, "llvm_windows_prefer_forward_slash", "")
if prefer_forward_slash in ("1", "ON", "True"):
config.environment["LLVM_WINDOWS_PREFER_FORWARD_SLASH"] = "1"
+
+ # Restrict forward-slash testing to a reasonable subset
+ # by excluding directories that don't deal with file paths or formatting
+ forward_slash_subsets = {"DebugInfo", "MC", "Support", "tools", "Unit"}
+ for subdir in os.listdir(config.test_source_root):
+ subdir_path = os.path.join(config.test_source_root, subdir)
+ if os.path.isdir(subdir_path) and subdir not in forward_slash_subsets:
+ config.excludes.append(subdir)
elif prefer_forward_slash in ("0", "OFF", "False"):
config.environment["LLVM_WINDOWS_PREFER_FORWARD_SLASH"] = "0"
diff --git a/llvm/utils/lit/lit/TestRunner.py b/llvm/utils/lit/lit/TestRunner.py
index 1b0f4ad4eebef..54cc25379c744 100644
--- a/llvm/utils/lit/lit/TestRunner.py
+++ b/llvm/utils/lit/lit/TestRunner.py
@@ -708,7 +708,8 @@ def make_tree(cmds):
results = []
timeoutInfo = None
- normalize_slashes = litConfig.params.get("use_normalized_slashes", False)
+ prefer_fs = getattr(test.config, "llvm_windows_prefer_forward_slash", "")
+ normalize_slashes = (prefer_fs in ("1", "ON", "True")) or litConfig.params.get("use_normalized_slashes", False)
shenv = ShellEnvironment(
cwd, test.config.environment, normalize_slashes=normalize_slashes
)
@@ -1937,6 +1938,7 @@ def executeShTest(
tmpDir,
tmpBase,
normalize_slashes=useExternalSh
+ or (getattr(test.config, "llvm_windows_prefer_forward_slash", "") in ("1", "ON", "True"))
or litConfig.params.get("use_normalized_slashes", False),
)
conditions = {feature: True for feature in test.config.available_features}
More information about the llvm-commits
mailing list