# -*- 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"

# testFormat: The test format to use to interpret tests.
config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell)

# 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"]

# 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.host_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))


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.
if re.search(r"cygwin|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 = "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("%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",
        "llvm-ar",
        "llvm-as",
        "llvm-addr2line",
        "llvm-bcanalyzer",
        "llvm-bitcode-strip",
        "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-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",
        "bugpoint",
        "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"),
    ]
)

# Find (major, minor) version of ptxas
def ptxas_version(ptxas):
    ptxas_cmd = subprocess.Popen([ptxas, "--version"], stdout=subprocess.PIPE)
    ptxas_out = ptxas_cmd.stdout.read().decode("ascii")
    ptxas_cmd.wait()
    match = re.search(r"release (\d+)\.(\d+)", ptxas_out)
    if match:
        return (int(match.group(1)), int(match.group(2)))
    print("couldn't determine ptxas version")
    return None


# Enable %ptxas and %ptxas-verify tools.
# %ptxas-verify defaults to sm_60 architecture. It can be overriden
# by specifying required one, for instance: %ptxas-verify -arch=sm_80.
def enable_ptxas(ptxas_executable):
    version = ptxas_version(ptxas_executable)
    if version:
        # ptxas is supposed to be backward compatible with previous
        # versions, so add a feature for every known version prior to
        # the current one.
        ptxas_known_versions = [
            (9, 0),
            (9, 1),
            (9, 2),
            (10, 0),
            (10, 1),
            (10, 2),
            (11, 0),
            (11, 1),
            (11, 2),
            (11, 3),
            (11, 4),
            (11, 5),
            (11, 6),
            (11, 7),
            (11, 8),
            (12, 0),
            (12, 1),
            (12, 2),
            (12, 3),
            (12, 4),
            (12, 5),
            (12, 6),
            (12, 8),
        ]

        def version_int(ver):
            return ver[0] * 100 + ver[1]

        # ignore ptxas if its version is below the minimum supported
        # version
        min_version = ptxas_known_versions[0]
        if version_int(version) < version_int(min_version):
            print(
                "Warning: ptxas version {}.{} is not supported".format(
                    version[0], version[1]
                )
            )
            return

        for known_version in ptxas_known_versions:
            if version_int(known_version) <= version_int(version):
                major, minor = known_version
                config.available_features.add("ptxas-{}.{}".format(major, minor))

    config.available_features.add("ptxas")
    tools.extend(
        [
            ToolSubst("%ptxas", ptxas_executable),
            ToolSubst("%ptxas-verify", "{} -arch=sm_60 -c -".format(ptxas_executable)),
        ]
    )


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|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"]:
    # ExecutionEngine, no weak symbols in COFF.
    config.available_features.add("uses_COFF")
else:
    # 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.build_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 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("ascii")
    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-gnu|windows-msvc|aix)",
    config.target_triple,
) and not re.match(r"^arm64(e)?-apple-(macos|darwin)", 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 "MemoryWithOrigins" in config.llvm_use_sanitizer:
    config.available_features.add("use_msan_with_origins")


# 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")
