CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
865 lines
28 KiB
Python
865 lines
28 KiB
Python
# -*- Python -*-
|
|
|
|
# Configuration file for the 'lit' test runner.
|
|
|
|
import os
|
|
import sys
|
|
import re
|
|
import platform
|
|
import subprocess
|
|
|
|
import lit.util
|
|
import lit.formats
|
|
from lit.llvm import llvm_config
|
|
from lit.llvm.subst import FindTool
|
|
from lit.llvm.subst import ToolSubst
|
|
|
|
# name: The name of this test suite.
|
|
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.
|
|
#
|
|
# We prefer the lit internal shell which provides a better user experience on failures
|
|
# and is faster unless the user explicitly disables it with LIT_USE_INTERNAL_SHELL=0
|
|
# env var.
|
|
use_lit_shell = True
|
|
lit_shell_env = os.environ.get("LIT_USE_INTERNAL_SHELL")
|
|
if lit_shell_env:
|
|
use_lit_shell = lit.util.pythonize_bool(lit_shell_env)
|
|
|
|
# testFormat: The test format to use to interpret tests.
|
|
extra_substitutions = extra_substitutions = (
|
|
[
|
|
(r"not FileCheck .*", "cat > /dev/null"),
|
|
(r"FileCheck .*", "cat > /dev/null"),
|
|
]
|
|
if config.enable_profcheck
|
|
else []
|
|
)
|
|
config.test_format = lit.formats.ShTest(not use_lit_shell, extra_substitutions)
|
|
|
|
# suffixes: A list of file extensions to treat as test files. This is overriden
|
|
# by individual lit.local.cfg files in the test subdirectories.
|
|
config.suffixes = [".ll", ".c", ".test", ".txt", ".s", ".mir", ".yaml", ".spv"]
|
|
|
|
# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
|
|
# subdirectories contain auxiliary inputs for various tests in their parent
|
|
# directories.
|
|
config.excludes = ["Inputs", "CMakeLists.txt", "README.txt", "LICENSE.txt"]
|
|
|
|
if config.enable_profcheck:
|
|
config.available_features.add("profcheck")
|
|
# Exclude llvm-reduce tests for profcheck because we substitute the FileCheck
|
|
# binary with a no-op command for profcheck, but llvm-reduce tests have RUN
|
|
# commands of the form llvm-reduce --test FileCheck, which explode if we
|
|
# substitute FileCheck because llvm-reduce expects FileCheck in these tests.
|
|
# It's not really possible to exclude these tests from the command substitution,
|
|
# so we just exclude llvm-reduce tests from this config altogether. This should
|
|
# be fine though as profcheck config tests are mostly concerned with opt.
|
|
config.excludes.append("llvm-reduce")
|
|
# Exclude llvm-objcopy tests - not the target of this effort, and some use
|
|
# cat in ways that conflict with how profcheck uses it.
|
|
config.excludes.append("llvm-objcopy")
|
|
# (Issue #161235) Temporarily exclude LoopVectorize.
|
|
config.excludes.append("LoopVectorize")
|
|
# Exclude suites that fail due to inserted profile annotations.
|
|
config.excludes.extend(["UpdateTestChecks", "Bitcode"])
|
|
# TODO(#166655): Reenable Instrumentation tests
|
|
config.excludes.append("Instrumentation")
|
|
# profiling doesn't work quite well on GPU, excluding
|
|
config.excludes.append("AMDGPU")
|
|
# TODO targets where profiling may make sense but will be addressed later
|
|
config.excludes.extend(
|
|
["Hexagon", "NVPTX", "PowerPC", "RISCV", "SPARC", "SPIRV", "WebAssembly"]
|
|
)
|
|
# these passes aren't hooked up to the pass pipeline:
|
|
config.excludes.extend(["IRCE", "LoopBoundSplit", "LoopInterchange", "Scalarizer"])
|
|
# Not on by default in any standard CPU pipeline.
|
|
config.excludes.extend(
|
|
[
|
|
"Attributor",
|
|
"IROutliner",
|
|
"BlockExtractor",
|
|
"CodeExtractor",
|
|
"HotColdSplit",
|
|
"LowerGlobalDestructors",
|
|
"LowerSwitch",
|
|
"StructurizeCFG",
|
|
"UnifyLoopExits",
|
|
]
|
|
)
|
|
# Not aimed at being used for peak-optimized binaries. These will be
|
|
# addressed later. PhaseOrdering has a couple of merge function tests.
|
|
config.excludes.extend(["GCOVProfiling", "MergeFunc", "PhaseOrdering"])
|
|
|
|
# test_source_root: The root path where tests are located.
|
|
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")
|
|
|
|
# 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"])
|
|
|
|
|
|
# Set up OCAMLPATH to include newly built OCaml libraries.
|
|
top_ocaml_lib = os.path.join(config.llvm_lib_dir, "ocaml")
|
|
llvm_ocaml_lib = os.path.join(top_ocaml_lib, "llvm")
|
|
|
|
llvm_config.with_system_environment("OCAMLPATH")
|
|
llvm_config.with_environment("OCAMLPATH", top_ocaml_lib, append_path=True)
|
|
llvm_config.with_environment("OCAMLPATH", llvm_ocaml_lib, append_path=True)
|
|
|
|
llvm_config.with_system_environment("CAML_LD_LIBRARY_PATH")
|
|
llvm_config.with_environment("CAML_LD_LIBRARY_PATH", llvm_ocaml_lib, append_path=True)
|
|
|
|
# Set up OCAMLRUNPARAM to enable backtraces in OCaml tests.
|
|
llvm_config.with_environment("OCAMLRUNPARAM", "b")
|
|
|
|
# Provide the path to asan runtime lib 'libclang_rt.asan_osx_dynamic.dylib' if
|
|
# available. This is darwin specific since it's currently only needed on darwin.
|
|
|
|
|
|
def get_asan_rtlib():
|
|
if (
|
|
not "Address" in config.llvm_use_sanitizer
|
|
or not "Darwin" in config.target_os
|
|
or not "x86" in config.host_triple
|
|
):
|
|
return ""
|
|
try:
|
|
import glob
|
|
except:
|
|
print("glob module not found, skipping get_asan_rtlib() lookup")
|
|
return ""
|
|
# The libclang_rt.asan_osx_dynamic.dylib path is obtained using the relative
|
|
# path from the host cc.
|
|
host_lib_dir = os.path.join(os.path.dirname(config.host_cc), "../lib")
|
|
asan_dylib_dir_pattern = (
|
|
host_lib_dir + "/clang/*/lib/darwin/libclang_rt.asan_osx_dynamic.dylib"
|
|
)
|
|
found_dylibs = glob.glob(asan_dylib_dir_pattern)
|
|
if len(found_dylibs) != 1:
|
|
return ""
|
|
return found_dylibs[0]
|
|
|
|
|
|
llvm_config.use_default_substitutions()
|
|
|
|
# Add site-specific substitutions.
|
|
config.substitutions.append(("%llvmshlibdir", config.llvm_shlib_dir))
|
|
config.substitutions.append(("%shlibext", config.llvm_shlib_ext))
|
|
config.substitutions.append(("%pluginext", config.llvm_plugin_ext))
|
|
config.substitutions.append(("%exeext", config.llvm_exe_ext))
|
|
config.substitutions.append(("%llvm_src_root", config.llvm_src_root))
|
|
|
|
# Add IR2Vec test vocabulary path substitution
|
|
config.substitutions.append(
|
|
(
|
|
"%ir2vec_test_vocab_dir",
|
|
os.path.join(config.test_source_root, "Analysis", "IR2Vec", "Inputs"),
|
|
)
|
|
)
|
|
|
|
lli_args = []
|
|
# The target triple used by default by lli is the process target triple (some
|
|
# triple appropriate for generating code for the current process) but because
|
|
# we don't support COFF in MCJIT well enough for the tests, force ELF format on
|
|
# Windows. FIXME: the process target triple should be used here, but this is
|
|
# difficult to obtain on Windows.
|
|
# Cygwin is excluded from this workaround, even though it is COFF, because this
|
|
# breaks remote tests due to not having a __register_frame function. The only
|
|
# test that succeeds with cygwin-elf but fails with cygwin is
|
|
# test/ExecutionEngine/MCJIT/stubs-sm-pic.ll so this test is marked as XFAIL
|
|
# for cygwin targets.
|
|
if re.search(r"windows-gnu|windows-msvc", config.host_triple):
|
|
lli_args = ["-mtriple=" + config.host_triple + "-elf"]
|
|
|
|
llc_args = []
|
|
|
|
# Similarly, have a macro to use llc with DWARF even when the host is Windows
|
|
if re.search(r"windows-msvc", config.target_triple):
|
|
llc_args = [" -mtriple=" + config.target_triple.replace("-msvc", "-gnu")]
|
|
|
|
# Provide the path to asan runtime lib if available. On darwin, this lib needs
|
|
# to be loaded via DYLD_INSERT_LIBRARIES before libLTO.dylib in case the files
|
|
# to be linked contain instrumented sanitizer code.
|
|
ld64_cmd = config.ld64_executable
|
|
asan_rtlib = get_asan_rtlib()
|
|
if asan_rtlib:
|
|
ld64_cmd = "env DYLD_INSERT_LIBRARIES={} {}".format(asan_rtlib, ld64_cmd)
|
|
if config.osx_sysroot:
|
|
ld64_cmd = "{} -syslibroot {}".format(ld64_cmd, config.osx_sysroot)
|
|
|
|
ocamlc_command = "%s ocamlc -cclib -L%s %s" % (
|
|
config.ocamlfind_executable,
|
|
config.llvm_lib_dir,
|
|
config.ocaml_flags,
|
|
)
|
|
ocamlopt_command = "true"
|
|
if config.have_ocamlopt:
|
|
ocamlopt_command = "%s ocamlopt -cclib -L%s -cclib -Wl,-rpath,%s %s" % (
|
|
config.ocamlfind_executable,
|
|
config.llvm_lib_dir,
|
|
config.llvm_lib_dir,
|
|
config.ocaml_flags,
|
|
)
|
|
|
|
opt_viewer_cmd = "%s %s/tools/opt-viewer/opt-viewer.py" % (
|
|
sys.executable,
|
|
config.llvm_src_root,
|
|
)
|
|
|
|
llvm_original_di_preservation_cmd = os.path.join(
|
|
config.llvm_src_root, "utils", "llvm-original-di-preservation.py"
|
|
)
|
|
config.substitutions.append(
|
|
(
|
|
"%llvm-original-di-preservation",
|
|
"'%s' %s" % (config.python_executable, llvm_original_di_preservation_cmd),
|
|
)
|
|
)
|
|
|
|
llvm_locstats_tool = os.path.join(config.llvm_tools_dir, "llvm-locstats")
|
|
config.substitutions.append(
|
|
("%llvm-locstats", "'%s' %s" % (config.python_executable, llvm_locstats_tool))
|
|
)
|
|
config.llvm_locstats_used = os.path.exists(llvm_locstats_tool)
|
|
|
|
tools = [
|
|
ToolSubst("%llvm", FindTool("llvm"), unresolved="ignore"),
|
|
ToolSubst("%lli", FindTool("lli"), post=".", extra_args=lli_args),
|
|
ToolSubst("%llc_dwarf", FindTool("llc"), extra_args=llc_args),
|
|
ToolSubst("%gold", config.gold_executable, unresolved="ignore"),
|
|
ToolSubst("%ld64", ld64_cmd, unresolved="ignore"),
|
|
ToolSubst("%ocamlc", ocamlc_command, unresolved="ignore"),
|
|
ToolSubst("%ocamlopt", ocamlopt_command, unresolved="ignore"),
|
|
ToolSubst("%opt-viewer", opt_viewer_cmd),
|
|
ToolSubst("%llvm-objcopy", FindTool("llvm-objcopy")),
|
|
ToolSubst("%llvm-strip", FindTool("llvm-strip")),
|
|
ToolSubst("%llvm-install-name-tool", FindTool("llvm-install-name-tool")),
|
|
ToolSubst("%llvm-bitcode-strip", FindTool("llvm-bitcode-strip")),
|
|
ToolSubst("%llvm-extract-bundle-entry", FindTool("llvm-extract-bundle-entry")),
|
|
ToolSubst("%split-file", FindTool("split-file")),
|
|
]
|
|
|
|
# FIXME: Why do we have both `lli` and `%lli` that do slightly different things?
|
|
tools.extend(
|
|
[
|
|
"dsymutil",
|
|
"lli",
|
|
"lli-child-target",
|
|
"llubi",
|
|
"llvm-ar",
|
|
"llvm-as",
|
|
"llvm-addr2line",
|
|
"llvm-bcanalyzer",
|
|
"llvm-bitcode-strip",
|
|
"llvm-cas",
|
|
"llvm-cgdata",
|
|
"llvm-config",
|
|
"llvm-cov",
|
|
"llvm-ctxprof-util",
|
|
"llvm-cxxdump",
|
|
"llvm-cvtres",
|
|
"llvm-debuginfod-find",
|
|
"llvm-debuginfo-analyzer",
|
|
"llvm-diff",
|
|
"llvm-dis",
|
|
"llvm-dwarfdump",
|
|
"llvm-dwarfutil",
|
|
"llvm-dwp",
|
|
"llvm-dlltool",
|
|
"llvm-exegesis",
|
|
"llvm-extract",
|
|
"llvm-extract-bundle-entry",
|
|
"llvm-ir2vec",
|
|
"llvm-isel-fuzzer",
|
|
"llvm-ifs",
|
|
"llvm-install-name-tool",
|
|
"llvm-jitlink",
|
|
"llvm-opt-fuzzer",
|
|
"llvm-lib",
|
|
"llvm-link",
|
|
"llvm-lto",
|
|
"llvm-lto2",
|
|
"llvm-mc",
|
|
"llvm-mca",
|
|
"llvm-modextract",
|
|
"llvm-nm",
|
|
"llvm-objcopy",
|
|
"llvm-objdump",
|
|
"llvm-otool",
|
|
"llvm-pdbutil",
|
|
"llvm-profdata",
|
|
"llvm-profgen",
|
|
"llvm-ranlib",
|
|
"llvm-rc",
|
|
"llvm-readelf",
|
|
"llvm-readobj",
|
|
"llvm-rtdyld",
|
|
"llvm-sim",
|
|
"llvm-size",
|
|
"llvm-split",
|
|
"llvm-stress",
|
|
"llvm-strings",
|
|
"llvm-strip",
|
|
"llvm-tblgen",
|
|
"llvm-readtapi",
|
|
"llvm-undname",
|
|
"llvm-windres",
|
|
"llvm-c-test",
|
|
"llvm-cxxfilt",
|
|
"llvm-xray",
|
|
"yaml2obj",
|
|
"obj2yaml",
|
|
"yaml-bench",
|
|
"verify-uselistorder",
|
|
"llc",
|
|
"llvm-symbolizer",
|
|
"opt",
|
|
"sancov",
|
|
"sanstats",
|
|
"llvm-remarkutil",
|
|
]
|
|
)
|
|
|
|
# The following tools are optional
|
|
tools.extend(
|
|
[
|
|
ToolSubst("llvm-mt", unresolved="ignore"),
|
|
ToolSubst("llvm-debuginfod", unresolved="ignore"),
|
|
ToolSubst("Kaleidoscope-Ch3", unresolved="ignore"),
|
|
ToolSubst("Kaleidoscope-Ch4", unresolved="ignore"),
|
|
ToolSubst("Kaleidoscope-Ch5", unresolved="ignore"),
|
|
ToolSubst("Kaleidoscope-Ch6", unresolved="ignore"),
|
|
ToolSubst("Kaleidoscope-Ch7", unresolved="ignore"),
|
|
ToolSubst("Kaleidoscope-Ch8", unresolved="ignore"),
|
|
ToolSubst("LLJITWithThinLTOSummaries", unresolved="ignore"),
|
|
ToolSubst("LLJITWithRemoteDebugging", unresolved="ignore"),
|
|
ToolSubst("OrcV2CBindingsBasicUsage", unresolved="ignore"),
|
|
ToolSubst("OrcV2CBindingsAddObjectFile", unresolved="ignore"),
|
|
ToolSubst("OrcV2CBindingsRemovableCode", unresolved="ignore"),
|
|
ToolSubst("OrcV2CBindingsLazy", unresolved="ignore"),
|
|
ToolSubst("OrcV2CBindingsVeryLazy", unresolved="ignore"),
|
|
ToolSubst("dxil-dis", unresolved="ignore"),
|
|
]
|
|
)
|
|
|
|
|
|
def ptxas_version(ptxas):
|
|
output = subprocess.check_output([ptxas, "--version"], text=True)
|
|
match = re.search(r"release (\d+)\.(\d+)", output)
|
|
if not match:
|
|
raise RuntimeError("Couldn't determine ptxas version")
|
|
return int(match.group(1)), int(match.group(2))
|
|
|
|
|
|
def ptxas_isa_versions(ptxas):
|
|
result = subprocess.run(
|
|
[ptxas, "--list-version"],
|
|
capture_output=True,
|
|
text=True,
|
|
)
|
|
versions = []
|
|
for line in result.stdout.splitlines():
|
|
match = re.match(r"(\d+)\.(\d+)", line)
|
|
if match:
|
|
versions.append((int(match.group(1)), int(match.group(2))))
|
|
return versions
|
|
|
|
|
|
def ptxas_supported_isa_versions(ptxas, major_version, minor_version):
|
|
supported_isa_versions = ptxas_isa_versions(ptxas)
|
|
if supported_isa_versions:
|
|
return supported_isa_versions
|
|
if major_version >= 13:
|
|
raise RuntimeError(f"ptxas {ptxas} does not support ISA version listing")
|
|
|
|
cuda_version_to_isa_version = {
|
|
(12, 9): [(8, 8)],
|
|
(12, 8): [(8, 7)],
|
|
(12, 7): [(8, 6)],
|
|
(12, 6): [(8, 5)],
|
|
(12, 5): [(8, 5)],
|
|
(12, 4): [(8, 4)],
|
|
(12, 3): [(8, 3)],
|
|
(12, 2): [(8, 2)],
|
|
(12, 1): [(8, 1)],
|
|
(12, 0): [(8, 0)],
|
|
(11, 8): [(7, 8)],
|
|
(11, 7): [(7, 7)],
|
|
(11, 6): [(7, 6)],
|
|
(11, 5): [(7, 5)],
|
|
(11, 4): [(7, 4)],
|
|
(11, 3): [(7, 3)],
|
|
(11, 2): [(7, 2)],
|
|
(11, 1): [(7, 1)],
|
|
(11, 0): [(7, 0)],
|
|
(10, 2): [(6, 5)],
|
|
(10, 1): [(6, 4)],
|
|
(10, 0): [(6, 3)],
|
|
(9, 2): [(6, 2)],
|
|
(9, 1): [(6, 1)],
|
|
(9, 0): [(6, 0)],
|
|
(8, 0): [(5, 0)],
|
|
(7, 5): [(4, 3)],
|
|
(7, 0): [(4, 2)],
|
|
(6, 5): [(4, 1)],
|
|
(6, 0): [(4, 0)],
|
|
(5, 5): [(3, 2)],
|
|
(5, 0): [(3, 1)],
|
|
(4, 1): [(3, 0)],
|
|
(4, 0): [(2, 3)],
|
|
(3, 2): [(2, 2)],
|
|
(3, 1): [(2, 1)],
|
|
(3, 0): [(2, 0), (1, 5)],
|
|
(2, 2): [(1, 4)],
|
|
(2, 1): [(1, 3)],
|
|
(2, 0): [(1, 2)],
|
|
(1, 1): [(1, 1)],
|
|
(1, 0): [(1, 0)],
|
|
}
|
|
|
|
supported_isa_versions = []
|
|
for (major, minor), isa_versions in cuda_version_to_isa_version.items():
|
|
if (major, minor) <= (major_version, minor_version):
|
|
for isa_version in isa_versions:
|
|
supported_isa_versions.append(isa_version)
|
|
return supported_isa_versions
|
|
|
|
|
|
def ptxas_supported_sms(ptxas_executable):
|
|
output = subprocess.check_output([ptxas_executable, "--help"], text=True)
|
|
|
|
gpu_arch_section = re.search(r"--gpu-name(.*?)--", output, re.DOTALL)
|
|
allowed_values = gpu_arch_section.group(1)
|
|
supported_sms = re.findall(r"'sm_(\d+(?:[af]?))'", allowed_values)
|
|
|
|
if not supported_sms:
|
|
raise RuntimeError("No SM architecture values found in ptxas help output")
|
|
return supported_sms
|
|
|
|
|
|
def ptxas_supports_address_size_32(ptxas_executable):
|
|
# Linux outputs the error message to stderr, while Windows outputs to stdout.
|
|
# Pipe both to stdout to make sure we get the error message.
|
|
result = subprocess.run(
|
|
[ptxas_executable, "-m 32"],
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.STDOUT,
|
|
text=True,
|
|
)
|
|
if "is not defined for option 'machine'" in result.stdout:
|
|
return False
|
|
if "Missing .version directive at start of file" in result.stdout:
|
|
return True
|
|
raise RuntimeError(f"Unexpected ptxas output: {result.stdout}")
|
|
|
|
|
|
def enable_ptxas(ptxas_executable):
|
|
config.available_features.add("ptxas")
|
|
tools.extend(
|
|
[
|
|
ToolSubst("%ptxas", ptxas_executable),
|
|
ToolSubst("%ptxas-verify", f"{ptxas_executable} -c -"),
|
|
]
|
|
)
|
|
|
|
major_version, minor_version = ptxas_version(ptxas_executable)
|
|
config.available_features.add(f"ptxas-{major_version}.{minor_version}")
|
|
|
|
for major, minor in ptxas_supported_isa_versions(
|
|
ptxas_executable, major_version, minor_version
|
|
):
|
|
config.available_features.add(f"ptxas-isa-{major}.{minor}")
|
|
|
|
for sm in ptxas_supported_sms(ptxas_executable):
|
|
config.available_features.add(f"ptxas-sm_{sm}")
|
|
|
|
if ptxas_supports_address_size_32(ptxas_executable):
|
|
config.available_features.add("ptxas-ptr32")
|
|
|
|
|
|
ptxas_executable = (
|
|
os.environ.get("LLVM_PTXAS_EXECUTABLE", None) or config.ptxas_executable
|
|
)
|
|
if ptxas_executable:
|
|
enable_ptxas(ptxas_executable)
|
|
|
|
llvm_config.add_tool_substitutions(tools, config.llvm_tools_dir)
|
|
|
|
# Targets
|
|
|
|
config.targets = frozenset(config.targets_to_build.split())
|
|
|
|
for arch in config.targets_to_build.split():
|
|
config.available_features.add(arch.lower() + "-registered-target")
|
|
|
|
# Features
|
|
known_arches = ["x86_64", "mips64", "ppc64", "aarch64"]
|
|
if config.host_ldflags.find("-m32") < 0 and any(
|
|
config.llvm_host_triple.startswith(x) for x in known_arches
|
|
):
|
|
config.available_features.add("llvm-64-bits")
|
|
|
|
config.available_features.add("host-byteorder-" + sys.byteorder + "-endian")
|
|
if config.target_triple:
|
|
if re.match(
|
|
r"(aarch64_be|arc|armeb|bpfeb|lanai|m68k|mips|mips64|powerpc|powerpc64|sparc|sparcv9|sparc64|s390x|s390|tce|thumbeb)-.*",
|
|
config.target_triple,
|
|
):
|
|
config.available_features.add("target-byteorder-big-endian")
|
|
else:
|
|
config.available_features.add("target-byteorder-little-endian")
|
|
|
|
if sys.platform in ["win32", "cygwin"]:
|
|
# ExecutionEngine, no weak symbols in COFF.
|
|
config.available_features.add("uses_COFF")
|
|
|
|
if sys.platform not in ["win32"]:
|
|
# Others/can-execute.txt
|
|
config.available_features.add("can-execute")
|
|
|
|
# Detect Windows Subsystem for Linux (WSL)
|
|
uname_r = platform.uname().release
|
|
if uname_r.endswith("-Microsoft"):
|
|
config.available_features.add("wsl1")
|
|
elif uname_r.endswith("microsoft-standard-WSL2"):
|
|
config.available_features.add("wsl2")
|
|
|
|
# Loadable module
|
|
if config.has_plugins:
|
|
config.available_features.add("plugins")
|
|
|
|
if config.include_examples:
|
|
config.available_features.add("examples")
|
|
|
|
if config.linked_bye_extension:
|
|
config.substitutions.append(("%llvmcheckext", "CHECK-EXT"))
|
|
config.substitutions.append(("%loadbye", ""))
|
|
config.substitutions.append(("%loadnewpmbye", ""))
|
|
else:
|
|
config.substitutions.append(("%llvmcheckext", "CHECK-NOEXT"))
|
|
config.substitutions.append(
|
|
(
|
|
"%loadbye",
|
|
"-load={}/Bye{}".format(config.llvm_shlib_dir, config.llvm_shlib_ext),
|
|
)
|
|
)
|
|
config.substitutions.append(
|
|
(
|
|
"%loadnewpmbye",
|
|
"-load-pass-plugin={}/Bye{}".format(
|
|
config.llvm_shlib_dir, config.llvm_shlib_ext
|
|
),
|
|
)
|
|
)
|
|
|
|
if config.linked_exampleirtransforms_extension:
|
|
config.substitutions.append(("%loadexampleirtransforms", ""))
|
|
else:
|
|
config.substitutions.append(
|
|
(
|
|
"%loadexampleirtransforms",
|
|
"-load-pass-plugin={}/ExampleIRTransforms{}".format(
|
|
config.llvm_shlib_dir, config.llvm_shlib_ext
|
|
),
|
|
)
|
|
)
|
|
|
|
# Static libraries are not built if BUILD_SHARED_LIBS is ON.
|
|
if not config.build_shared_libs and not config.link_llvm_dylib:
|
|
config.available_features.add("static-libs")
|
|
|
|
if config.link_llvm_dylib:
|
|
config.available_features.add("llvm-dylib")
|
|
config.substitutions.append(
|
|
(
|
|
# libLLVM.so.19.0git
|
|
"%llvmdylib",
|
|
"{}/libLLVM{}.{}".format(
|
|
config.llvm_shlib_dir, config.llvm_shlib_ext, config.llvm_dylib_version
|
|
),
|
|
)
|
|
)
|
|
|
|
if config.have_tf_aot:
|
|
config.available_features.add("have_tf_aot")
|
|
|
|
if getattr(config, "have_opencsd", False):
|
|
config.available_features.add("opencsd")
|
|
|
|
if config.have_tflite:
|
|
config.available_features.add("have_tflite")
|
|
|
|
if config.llvm_inliner_model_autogenerated:
|
|
config.available_features.add("llvm_inliner_model_autogenerated")
|
|
|
|
if config.llvm_raevict_model_autogenerated:
|
|
config.available_features.add("llvm_raevict_model_autogenerated")
|
|
|
|
|
|
def have_cxx_shared_library():
|
|
readobj_exe = lit.util.which("llvm-readobj", config.llvm_tools_dir)
|
|
if not readobj_exe:
|
|
print("llvm-readobj not found")
|
|
return False
|
|
|
|
try:
|
|
readobj_cmd = subprocess.Popen(
|
|
[readobj_exe, "--needed-libs", readobj_exe], stdout=subprocess.PIPE
|
|
)
|
|
except OSError:
|
|
print("could not exec llvm-readobj")
|
|
return False
|
|
|
|
readobj_out = readobj_cmd.stdout.read().decode("utf-8")
|
|
readobj_cmd.wait()
|
|
|
|
regex = re.compile(r"(libc\+\+|libstdc\+\+|msvcp).*\.(so|dylib|dll)")
|
|
needed_libs = False
|
|
for line in readobj_out.splitlines():
|
|
if "NeededLibraries [" in line:
|
|
needed_libs = True
|
|
if "]" in line:
|
|
needed_libs = False
|
|
if needed_libs and regex.search(line.lower()):
|
|
return True
|
|
return False
|
|
|
|
|
|
if have_cxx_shared_library():
|
|
config.available_features.add("cxx-shared-library")
|
|
|
|
if config.libcxx_used:
|
|
config.available_features.add("libcxx-used")
|
|
|
|
# LLVM can be configured with an empty default triple
|
|
# Some tests are "generic" and require a valid default triple
|
|
if config.target_triple:
|
|
config.available_features.add("default_triple")
|
|
# Direct object generation
|
|
if not config.target_triple.startswith(("nvptx", "xcore")):
|
|
config.available_features.add("object-emission")
|
|
|
|
if config.have_llvm_driver:
|
|
config.available_features.add("llvm-driver")
|
|
|
|
import subprocess
|
|
|
|
|
|
def have_ld_plugin_support():
|
|
if not os.path.exists(
|
|
os.path.join(config.llvm_shlib_dir, "LLVMgold" + config.llvm_shlib_ext)
|
|
):
|
|
return False
|
|
|
|
ld_cmd = subprocess.Popen(
|
|
[config.gold_executable, "--help"], stdout=subprocess.PIPE, env={"LANG": "C"}
|
|
)
|
|
ld_out = ld_cmd.stdout.read().decode()
|
|
ld_cmd.wait()
|
|
|
|
if not "-plugin" in ld_out:
|
|
return False
|
|
|
|
# check that the used emulations are supported.
|
|
emu_line = [l for l in ld_out.split("\n") if "supported emulations" in l]
|
|
if len(emu_line) != 1:
|
|
return False
|
|
emu_line = emu_line[0]
|
|
fields = emu_line.split(":")
|
|
if len(fields) != 3:
|
|
return False
|
|
emulations = fields[2].split()
|
|
if "elf_x86_64" not in emulations:
|
|
return False
|
|
if "elf32ppc" in emulations:
|
|
config.available_features.add("ld_emu_elf32ppc")
|
|
|
|
ld_version = subprocess.Popen(
|
|
[config.gold_executable, "--version"], stdout=subprocess.PIPE, env={"LANG": "C"}
|
|
)
|
|
if not "GNU gold" in ld_version.stdout.read().decode():
|
|
return False
|
|
ld_version.wait()
|
|
|
|
return True
|
|
|
|
|
|
if have_ld_plugin_support():
|
|
config.available_features.add("ld_plugin")
|
|
|
|
|
|
def have_ld64_plugin_support():
|
|
if not os.path.exists(
|
|
os.path.join(config.llvm_shlib_dir, "libLTO" + config.llvm_shlib_ext)
|
|
):
|
|
return False
|
|
|
|
if config.ld64_executable == "":
|
|
return False
|
|
|
|
ld_cmd = subprocess.Popen([config.ld64_executable, "-v"], stderr=subprocess.PIPE)
|
|
ld_out = ld_cmd.stderr.read().decode()
|
|
ld_cmd.wait()
|
|
|
|
if "ld64" not in ld_out or "LTO" not in ld_out:
|
|
return False
|
|
|
|
return True
|
|
|
|
|
|
if have_ld64_plugin_support():
|
|
config.available_features.add("ld64_plugin")
|
|
|
|
|
|
def host_unwind_supports_jit():
|
|
# Do we expect the host machine to support JIT registration of clang's
|
|
# default unwind info format for the host (e.g. eh-frames, compact-unwind,
|
|
# etc.).
|
|
|
|
# Linux and the BSDs use DWARF eh-frames and all known unwinders support
|
|
# register_frame at minimum.
|
|
if platform.system() in ["Linux", "FreeBSD", "NetBSD"]:
|
|
return True
|
|
|
|
# Windows does not support frame info without the ORC runtime.
|
|
if platform.system() == "Windows":
|
|
return False
|
|
|
|
# On Darwin/x86-64 clang produces both eh-frames and compact-unwind, and
|
|
# libunwind supports register_frame. On Darwin/arm64 clang produces
|
|
# compact-unwind only, and JIT'd registration is not available before
|
|
# macOS 14.0.
|
|
if platform.system() == "Darwin":
|
|
assert "arm64" in config.host_triple or "x86_64" in config.host_triple
|
|
|
|
if "x86_64" in config.host_triple:
|
|
return True
|
|
|
|
# Must be arm64. Check the macOS version.
|
|
try:
|
|
osx_version = subprocess.check_output(
|
|
["sw_vers", "-productVersion"], universal_newlines=True
|
|
)
|
|
osx_version = tuple(int(x) for x in osx_version.split("."))
|
|
if len(osx_version) == 2:
|
|
osx_version = (osx_version[0], osx_version[1], 0)
|
|
if osx_version >= (14, 0):
|
|
return True
|
|
except:
|
|
pass
|
|
|
|
return False
|
|
|
|
return False
|
|
|
|
|
|
if host_unwind_supports_jit():
|
|
config.available_features.add("host-unwind-supports-jit")
|
|
|
|
# Ask llvm-config about asserts
|
|
llvm_config.feature_config(
|
|
[
|
|
("--assertion-mode", {"ON": "asserts"}),
|
|
("--build-mode", {"[Dd][Ee][Bb][Uu][Gg]": "debug"}),
|
|
]
|
|
)
|
|
|
|
if "darwin" == sys.platform:
|
|
cmd = ["sysctl", "hw.optional.fma"]
|
|
sysctl_cmd = subprocess.Popen(cmd, stdout=subprocess.PIPE)
|
|
|
|
# Non zero return, probably a permission issue
|
|
if sysctl_cmd.wait():
|
|
print(
|
|
'Warning: sysctl exists but calling "{}" failed, defaulting to no fma3.'.format(
|
|
" ".join(cmd)
|
|
)
|
|
)
|
|
else:
|
|
result = sysctl_cmd.stdout.read().decode("ascii")
|
|
if "hw.optional.fma: 1" in result:
|
|
config.available_features.add("fma3")
|
|
|
|
if not hasattr(sys, "getwindowsversion") or sys.getwindowsversion().build >= 17063:
|
|
config.available_features.add("unix-sockets")
|
|
|
|
# .debug_frame is not emitted for targeting Windows x64, aarch64/arm64, AIX, or Apple Silicon Mac.
|
|
if (
|
|
not re.match(
|
|
r"^(x86_64|aarch64|arm64|powerpc|powerpc64).*-(windows-cygnus|windows-gnu|windows-msvc|aix)",
|
|
config.target_triple,
|
|
)
|
|
and not re.match(
|
|
r"^arm64(e)?-apple-(macos|darwin)",
|
|
config.target_triple,
|
|
)
|
|
and not re.match(r".*-zos.*", config.target_triple)
|
|
):
|
|
config.available_features.add("debug_frame")
|
|
|
|
if config.enable_backtrace:
|
|
config.available_features.add("backtrace")
|
|
|
|
if config.enable_threads:
|
|
config.available_features.add("thread_support")
|
|
|
|
if config.have_libxml2:
|
|
config.available_features.add("libxml2")
|
|
|
|
if config.have_curl:
|
|
config.available_features.add("curl")
|
|
|
|
if config.have_httplib:
|
|
config.available_features.add("httplib")
|
|
|
|
if config.have_opt_viewer_modules:
|
|
config.available_features.add("have_opt_viewer_modules")
|
|
|
|
if config.expensive_checks:
|
|
config.available_features.add("expensive_checks")
|
|
|
|
if config.have_ondisk_cas:
|
|
config.available_features.add("ondisk_cas")
|
|
|
|
if "MemoryWithOrigins" in config.llvm_use_sanitizer:
|
|
config.available_features.add("use_msan_with_origins")
|
|
|
|
if "Undefined" in config.llvm_use_sanitizer:
|
|
config.available_features.add("ubsan")
|
|
|
|
# Restrict the size of the on-disk CAS for tests. This allows testing in
|
|
# constrained environments (e.g. small TMPDIR). It also prevents leaving
|
|
# behind large files on file systems that do not support sparse files if a test
|
|
# crashes before resizing the file.
|
|
config.environment["LLVM_CAS_MAX_MAPPING_SIZE"] = "%d" % (100 * 1024 * 1024)
|
|
|
|
# Some tools support an environment variable "OBJECT_MODE" on AIX OS, which
|
|
# controls the kind of objects they will support. If there is no "OBJECT_MODE"
|
|
# environment variable specified, the default behaviour is to support 32-bit
|
|
# objects only. In order to not affect most test cases, which expect to support
|
|
# 32-bit and 64-bit objects by default, set the environment variable
|
|
# "OBJECT_MODE" to 'any' by default on AIX OS.
|
|
if "system-aix" in config.available_features:
|
|
config.environment["OBJECT_MODE"] = "any"
|
|
|
|
if config.has_logf128:
|
|
config.available_features.add("has_logf128")
|
|
|
|
if lit_config.update_tests:
|
|
import sys
|
|
import os
|
|
|
|
utilspath = os.path.join(config.llvm_src_root, "utils")
|
|
sys.path.append(utilspath)
|
|
from update_any_test_checks import utc_lit_plugin
|
|
|
|
lit_config.test_updaters.append(utc_lit_plugin)
|