1# -*- Python -*- 2 3# Configuration file for the 'lit' test runner. 4 5import os 6import sys 7import re 8import platform 9import subprocess 10 11import lit.util 12import lit.formats 13from lit.llvm import llvm_config 14from lit.llvm.subst import FindTool 15from lit.llvm.subst import ToolSubst 16 17# name: The name of this test suite. 18config.name = "LLVM" 19 20# testFormat: The test format to use to interpret tests. 21config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell) 22 23# suffixes: A list of file extensions to treat as test files. This is overriden 24# by individual lit.local.cfg files in the test subdirectories. 25config.suffixes = [".ll", ".c", ".test", ".txt", ".s", ".mir", ".yaml", ".spv"] 26 27# excludes: A list of directories to exclude from the testsuite. The 'Inputs' 28# subdirectories contain auxiliary inputs for various tests in their parent 29# directories. 30config.excludes = ["Inputs", "CMakeLists.txt", "README.txt", "LICENSE.txt"] 31 32# test_source_root: The root path where tests are located. 33config.test_source_root = os.path.dirname(__file__) 34 35# test_exec_root: The root path where tests should be run. 36config.test_exec_root = os.path.join(config.llvm_obj_root, "test") 37 38# Tweak the PATH to include the tools dir. 39llvm_config.with_environment("PATH", config.llvm_tools_dir, append_path=True) 40 41# Propagate some variables from the host environment. 42llvm_config.with_system_environment(["HOME", "INCLUDE", "LIB", "TMP", "TEMP"]) 43 44 45# Set up OCAMLPATH to include newly built OCaml libraries. 46top_ocaml_lib = os.path.join(config.llvm_lib_dir, "ocaml") 47llvm_ocaml_lib = os.path.join(top_ocaml_lib, "llvm") 48 49llvm_config.with_system_environment("OCAMLPATH") 50llvm_config.with_environment("OCAMLPATH", top_ocaml_lib, append_path=True) 51llvm_config.with_environment("OCAMLPATH", llvm_ocaml_lib, append_path=True) 52 53llvm_config.with_system_environment("CAML_LD_LIBRARY_PATH") 54llvm_config.with_environment("CAML_LD_LIBRARY_PATH", llvm_ocaml_lib, append_path=True) 55 56# Set up OCAMLRUNPARAM to enable backtraces in OCaml tests. 57llvm_config.with_environment("OCAMLRUNPARAM", "b") 58 59# Provide the path to asan runtime lib 'libclang_rt.asan_osx_dynamic.dylib' if 60# available. This is darwin specific since it's currently only needed on darwin. 61 62 63def get_asan_rtlib(): 64 if ( 65 not "Address" in config.llvm_use_sanitizer 66 or not "Darwin" in config.host_os 67 or not "x86" in config.host_triple 68 ): 69 return "" 70 try: 71 import glob 72 except: 73 print("glob module not found, skipping get_asan_rtlib() lookup") 74 return "" 75 # The libclang_rt.asan_osx_dynamic.dylib path is obtained using the relative 76 # path from the host cc. 77 host_lib_dir = os.path.join(os.path.dirname(config.host_cc), "../lib") 78 asan_dylib_dir_pattern = ( 79 host_lib_dir + "/clang/*/lib/darwin/libclang_rt.asan_osx_dynamic.dylib" 80 ) 81 found_dylibs = glob.glob(asan_dylib_dir_pattern) 82 if len(found_dylibs) != 1: 83 return "" 84 return found_dylibs[0] 85 86 87llvm_config.use_default_substitutions() 88 89# Add site-specific substitutions. 90config.substitutions.append(("%llvmshlibdir", config.llvm_shlib_dir)) 91config.substitutions.append(("%shlibext", config.llvm_shlib_ext)) 92config.substitutions.append(("%pluginext", config.llvm_plugin_ext)) 93config.substitutions.append(("%exeext", config.llvm_exe_ext)) 94 95 96lli_args = [] 97# The target triple used by default by lli is the process target triple (some 98# triple appropriate for generating code for the current process) but because 99# we don't support COFF in MCJIT well enough for the tests, force ELF format on 100# Windows. FIXME: the process target triple should be used here, but this is 101# difficult to obtain on Windows. 102if re.search(r"cygwin|windows-gnu|windows-msvc", config.host_triple): 103 lli_args = ["-mtriple=" + config.host_triple + "-elf"] 104 105llc_args = [] 106 107# Similarly, have a macro to use llc with DWARF even when the host is Windows 108if re.search(r"windows-msvc", config.target_triple): 109 llc_args = [" -mtriple=" + config.target_triple.replace("-msvc", "-gnu")] 110 111# Provide the path to asan runtime lib if available. On darwin, this lib needs 112# to be loaded via DYLD_INSERT_LIBRARIES before libLTO.dylib in case the files 113# to be linked contain instrumented sanitizer code. 114ld64_cmd = config.ld64_executable 115asan_rtlib = get_asan_rtlib() 116if asan_rtlib: 117 ld64_cmd = "DYLD_INSERT_LIBRARIES={} {}".format(asan_rtlib, ld64_cmd) 118if config.osx_sysroot: 119 ld64_cmd = "{} -syslibroot {}".format(ld64_cmd, config.osx_sysroot) 120 121ocamlc_command = "%s ocamlc -cclib -L%s %s" % ( 122 config.ocamlfind_executable, 123 config.llvm_lib_dir, 124 config.ocaml_flags, 125) 126ocamlopt_command = "true" 127if config.have_ocamlopt: 128 ocamlopt_command = "%s ocamlopt -cclib -L%s -cclib -Wl,-rpath,%s %s" % ( 129 config.ocamlfind_executable, 130 config.llvm_lib_dir, 131 config.llvm_lib_dir, 132 config.ocaml_flags, 133 ) 134 135opt_viewer_cmd = "%s %s/tools/opt-viewer/opt-viewer.py" % ( 136 sys.executable, 137 config.llvm_src_root, 138) 139 140llvm_original_di_preservation_cmd = os.path.join( 141 config.llvm_src_root, "utils", "llvm-original-di-preservation.py" 142) 143config.substitutions.append( 144 ( 145 "%llvm-original-di-preservation", 146 "'%s' %s" % (config.python_executable, llvm_original_di_preservation_cmd), 147 ) 148) 149 150llvm_locstats_tool = os.path.join(config.llvm_tools_dir, "llvm-locstats") 151config.substitutions.append( 152 ("%llvm-locstats", "'%s' %s" % (config.python_executable, llvm_locstats_tool)) 153) 154config.llvm_locstats_used = os.path.exists(llvm_locstats_tool) 155 156tools = [ 157 ToolSubst("%llvm", FindTool("llvm"), unresolved="ignore"), 158 ToolSubst("%lli", FindTool("lli"), post=".", extra_args=lli_args), 159 ToolSubst("%llc_dwarf", FindTool("llc"), extra_args=llc_args), 160 ToolSubst("%gold", config.gold_executable, unresolved="ignore"), 161 ToolSubst("%ld64", ld64_cmd, unresolved="ignore"), 162 ToolSubst("%ocamlc", ocamlc_command, unresolved="ignore"), 163 ToolSubst("%ocamlopt", ocamlopt_command, unresolved="ignore"), 164 ToolSubst("%opt-viewer", opt_viewer_cmd), 165 ToolSubst("%llvm-objcopy", FindTool("llvm-objcopy")), 166 ToolSubst("%llvm-strip", FindTool("llvm-strip")), 167 ToolSubst("%llvm-install-name-tool", FindTool("llvm-install-name-tool")), 168 ToolSubst("%llvm-bitcode-strip", FindTool("llvm-bitcode-strip")), 169 ToolSubst("%split-file", FindTool("split-file")), 170] 171 172# FIXME: Why do we have both `lli` and `%lli` that do slightly different things? 173tools.extend( 174 [ 175 "dsymutil", 176 "lli", 177 "lli-child-target", 178 "llvm-ar", 179 "llvm-as", 180 "llvm-addr2line", 181 "llvm-bcanalyzer", 182 "llvm-bitcode-strip", 183 "llvm-cgdata", 184 "llvm-config", 185 "llvm-cov", 186 "llvm-ctxprof-util", 187 "llvm-cxxdump", 188 "llvm-cvtres", 189 "llvm-debuginfod-find", 190 "llvm-debuginfo-analyzer", 191 "llvm-diff", 192 "llvm-dis", 193 "llvm-dwarfdump", 194 "llvm-dwarfutil", 195 "llvm-dwp", 196 "llvm-dlltool", 197 "llvm-exegesis", 198 "llvm-extract", 199 "llvm-isel-fuzzer", 200 "llvm-ifs", 201 "llvm-install-name-tool", 202 "llvm-jitlink", 203 "llvm-opt-fuzzer", 204 "llvm-lib", 205 "llvm-link", 206 "llvm-lto", 207 "llvm-lto2", 208 "llvm-mc", 209 "llvm-mca", 210 "llvm-modextract", 211 "llvm-nm", 212 "llvm-objcopy", 213 "llvm-objdump", 214 "llvm-otool", 215 "llvm-pdbutil", 216 "llvm-profdata", 217 "llvm-profgen", 218 "llvm-ranlib", 219 "llvm-rc", 220 "llvm-readelf", 221 "llvm-readobj", 222 "llvm-rtdyld", 223 "llvm-sim", 224 "llvm-size", 225 "llvm-split", 226 "llvm-stress", 227 "llvm-strings", 228 "llvm-strip", 229 "llvm-tblgen", 230 "llvm-readtapi", 231 "llvm-undname", 232 "llvm-windres", 233 "llvm-c-test", 234 "llvm-cxxfilt", 235 "llvm-xray", 236 "yaml2obj", 237 "obj2yaml", 238 "yaml-bench", 239 "verify-uselistorder", 240 "bugpoint", 241 "llc", 242 "llvm-symbolizer", 243 "opt", 244 "sancov", 245 "sanstats", 246 "llvm-remarkutil", 247 ] 248) 249 250# The following tools are optional 251tools.extend( 252 [ 253 ToolSubst("llvm-mt", unresolved="ignore"), 254 ToolSubst("llvm-debuginfod", unresolved="ignore"), 255 ToolSubst("Kaleidoscope-Ch3", unresolved="ignore"), 256 ToolSubst("Kaleidoscope-Ch4", unresolved="ignore"), 257 ToolSubst("Kaleidoscope-Ch5", unresolved="ignore"), 258 ToolSubst("Kaleidoscope-Ch6", unresolved="ignore"), 259 ToolSubst("Kaleidoscope-Ch7", unresolved="ignore"), 260 ToolSubst("Kaleidoscope-Ch8", unresolved="ignore"), 261 ToolSubst("LLJITWithThinLTOSummaries", unresolved="ignore"), 262 ToolSubst("LLJITWithRemoteDebugging", unresolved="ignore"), 263 ToolSubst("OrcV2CBindingsBasicUsage", unresolved="ignore"), 264 ToolSubst("OrcV2CBindingsAddObjectFile", unresolved="ignore"), 265 ToolSubst("OrcV2CBindingsRemovableCode", unresolved="ignore"), 266 ToolSubst("OrcV2CBindingsLazy", unresolved="ignore"), 267 ToolSubst("OrcV2CBindingsVeryLazy", unresolved="ignore"), 268 ToolSubst("dxil-dis", unresolved="ignore"), 269 ] 270) 271 272# Find (major, minor) version of ptxas 273def ptxas_version(ptxas): 274 ptxas_cmd = subprocess.Popen([ptxas, "--version"], stdout=subprocess.PIPE) 275 ptxas_out = ptxas_cmd.stdout.read().decode("ascii") 276 ptxas_cmd.wait() 277 match = re.search(r"release (\d+)\.(\d+)", ptxas_out) 278 if match: 279 return (int(match.group(1)), int(match.group(2))) 280 print("couldn't determine ptxas version") 281 return None 282 283 284# Enable %ptxas and %ptxas-verify tools. 285# %ptxas-verify defaults to sm_60 architecture. It can be overriden 286# by specifying required one, for instance: %ptxas-verify -arch=sm_80. 287def enable_ptxas(ptxas_executable): 288 version = ptxas_version(ptxas_executable) 289 if version: 290 # ptxas is supposed to be backward compatible with previous 291 # versions, so add a feature for every known version prior to 292 # the current one. 293 ptxas_known_versions = [ 294 (9, 0), 295 (9, 1), 296 (9, 2), 297 (10, 0), 298 (10, 1), 299 (10, 2), 300 (11, 0), 301 (11, 1), 302 (11, 2), 303 (11, 3), 304 (11, 4), 305 (11, 5), 306 (11, 6), 307 (11, 7), 308 (11, 8), 309 (12, 0), 310 (12, 1), 311 (12, 2), 312 (12, 3), 313 (12, 4), 314 (12, 5), 315 (12, 6), 316 (12, 8), 317 ] 318 319 def version_int(ver): 320 return ver[0] * 100 + ver[1] 321 322 # ignore ptxas if its version is below the minimum supported 323 # version 324 min_version = ptxas_known_versions[0] 325 if version_int(version) < version_int(min_version): 326 print( 327 "Warning: ptxas version {}.{} is not supported".format( 328 version[0], version[1] 329 ) 330 ) 331 return 332 333 for known_version in ptxas_known_versions: 334 if version_int(known_version) <= version_int(version): 335 major, minor = known_version 336 config.available_features.add("ptxas-{}.{}".format(major, minor)) 337 338 config.available_features.add("ptxas") 339 tools.extend( 340 [ 341 ToolSubst("%ptxas", ptxas_executable), 342 ToolSubst("%ptxas-verify", "{} -arch=sm_60 -c -".format(ptxas_executable)), 343 ] 344 ) 345 346 347ptxas_executable = ( 348 os.environ.get("LLVM_PTXAS_EXECUTABLE", None) or config.ptxas_executable 349) 350if ptxas_executable: 351 enable_ptxas(ptxas_executable) 352 353llvm_config.add_tool_substitutions(tools, config.llvm_tools_dir) 354 355# Targets 356 357config.targets = frozenset(config.targets_to_build.split()) 358 359for arch in config.targets_to_build.split(): 360 config.available_features.add(arch.lower() + "-registered-target") 361 362# Features 363known_arches = ["x86_64", "mips64", "ppc64", "aarch64"] 364if config.host_ldflags.find("-m32") < 0 and any( 365 config.llvm_host_triple.startswith(x) for x in known_arches 366): 367 config.available_features.add("llvm-64-bits") 368 369config.available_features.add("host-byteorder-" + sys.byteorder + "-endian") 370if config.target_triple: 371 if re.match( 372 r"(aarch64_be|arc|armeb|bpfeb|lanai|m68k|mips|mips64|powerpc|powerpc64|sparc|sparcv9|s390x|s390|tce|thumbeb)-.*", 373 config.target_triple, 374 ): 375 config.available_features.add("target-byteorder-big-endian") 376 else: 377 config.available_features.add("target-byteorder-little-endian") 378 379if sys.platform in ["win32"]: 380 # ExecutionEngine, no weak symbols in COFF. 381 config.available_features.add("uses_COFF") 382else: 383 # Others/can-execute.txt 384 config.available_features.add("can-execute") 385 386# Loadable module 387if config.has_plugins: 388 config.available_features.add("plugins") 389 390if config.build_examples: 391 config.available_features.add("examples") 392 393if config.linked_bye_extension: 394 config.substitutions.append(("%llvmcheckext", "CHECK-EXT")) 395 config.substitutions.append(("%loadbye", "")) 396 config.substitutions.append(("%loadnewpmbye", "")) 397else: 398 config.substitutions.append(("%llvmcheckext", "CHECK-NOEXT")) 399 config.substitutions.append( 400 ( 401 "%loadbye", 402 "-load={}/Bye{}".format(config.llvm_shlib_dir, config.llvm_shlib_ext), 403 ) 404 ) 405 config.substitutions.append( 406 ( 407 "%loadnewpmbye", 408 "-load-pass-plugin={}/Bye{}".format( 409 config.llvm_shlib_dir, config.llvm_shlib_ext 410 ), 411 ) 412 ) 413 414if config.linked_exampleirtransforms_extension: 415 config.substitutions.append(("%loadexampleirtransforms", "")) 416else: 417 config.substitutions.append( 418 ( 419 "%loadexampleirtransforms", 420 "-load-pass-plugin={}/ExampleIRTransforms{}".format( 421 config.llvm_shlib_dir, config.llvm_shlib_ext 422 ), 423 ) 424 ) 425 426# Static libraries are not built if BUILD_SHARED_LIBS is ON. 427if not config.build_shared_libs and not config.link_llvm_dylib: 428 config.available_features.add("static-libs") 429 430if config.link_llvm_dylib: 431 config.available_features.add("llvm-dylib") 432 config.substitutions.append( 433 ( 434 # libLLVM.so.19.0git 435 "%llvmdylib", 436 "{}/libLLVM{}.{}".format( 437 config.llvm_shlib_dir, config.llvm_shlib_ext, config.llvm_dylib_version 438 ) 439 ) 440 ) 441 442if config.have_tf_aot: 443 config.available_features.add("have_tf_aot") 444 445if config.have_tflite: 446 config.available_features.add("have_tflite") 447 448if config.llvm_inliner_model_autogenerated: 449 config.available_features.add("llvm_inliner_model_autogenerated") 450 451if config.llvm_raevict_model_autogenerated: 452 config.available_features.add("llvm_raevict_model_autogenerated") 453 454 455def have_cxx_shared_library(): 456 readobj_exe = lit.util.which("llvm-readobj", config.llvm_tools_dir) 457 if not readobj_exe: 458 print("llvm-readobj not found") 459 return False 460 461 try: 462 readobj_cmd = subprocess.Popen( 463 [readobj_exe, "--needed-libs", readobj_exe], stdout=subprocess.PIPE 464 ) 465 except OSError: 466 print("could not exec llvm-readobj") 467 return False 468 469 readobj_out = readobj_cmd.stdout.read().decode("ascii") 470 readobj_cmd.wait() 471 472 regex = re.compile(r"(libc\+\+|libstdc\+\+|msvcp).*\.(so|dylib|dll)") 473 needed_libs = False 474 for line in readobj_out.splitlines(): 475 if "NeededLibraries [" in line: 476 needed_libs = True 477 if "]" in line: 478 needed_libs = False 479 if needed_libs and regex.search(line.lower()): 480 return True 481 return False 482 483 484if have_cxx_shared_library(): 485 config.available_features.add("cxx-shared-library") 486 487if config.libcxx_used: 488 config.available_features.add("libcxx-used") 489 490# LLVM can be configured with an empty default triple 491# Some tests are "generic" and require a valid default triple 492if config.target_triple: 493 config.available_features.add("default_triple") 494 # Direct object generation 495 if not config.target_triple.startswith(("nvptx", "xcore")): 496 config.available_features.add("object-emission") 497 498if config.have_llvm_driver: 499 config.available_features.add("llvm-driver") 500 501import subprocess 502 503 504def have_ld_plugin_support(): 505 if not os.path.exists( 506 os.path.join(config.llvm_shlib_dir, "LLVMgold" + config.llvm_shlib_ext) 507 ): 508 return False 509 510 ld_cmd = subprocess.Popen( 511 [config.gold_executable, "--help"], stdout=subprocess.PIPE, env={"LANG": "C"} 512 ) 513 ld_out = ld_cmd.stdout.read().decode() 514 ld_cmd.wait() 515 516 if not "-plugin" in ld_out: 517 return False 518 519 # check that the used emulations are supported. 520 emu_line = [l for l in ld_out.split("\n") if "supported emulations" in l] 521 if len(emu_line) != 1: 522 return False 523 emu_line = emu_line[0] 524 fields = emu_line.split(":") 525 if len(fields) != 3: 526 return False 527 emulations = fields[2].split() 528 if "elf_x86_64" not in emulations: 529 return False 530 if "elf32ppc" in emulations: 531 config.available_features.add("ld_emu_elf32ppc") 532 533 ld_version = subprocess.Popen( 534 [config.gold_executable, "--version"], stdout=subprocess.PIPE, env={"LANG": "C"} 535 ) 536 if not "GNU gold" in ld_version.stdout.read().decode(): 537 return False 538 ld_version.wait() 539 540 return True 541 542 543if have_ld_plugin_support(): 544 config.available_features.add("ld_plugin") 545 546 547def have_ld64_plugin_support(): 548 if not os.path.exists( 549 os.path.join(config.llvm_shlib_dir, "libLTO" + config.llvm_shlib_ext) 550 ): 551 return False 552 553 if config.ld64_executable == "": 554 return False 555 556 ld_cmd = subprocess.Popen([config.ld64_executable, "-v"], stderr=subprocess.PIPE) 557 ld_out = ld_cmd.stderr.read().decode() 558 ld_cmd.wait() 559 560 if "ld64" not in ld_out or "LTO" not in ld_out: 561 return False 562 563 return True 564 565 566if have_ld64_plugin_support(): 567 config.available_features.add("ld64_plugin") 568 569# Ask llvm-config about asserts 570llvm_config.feature_config( 571 [ 572 ("--assertion-mode", {"ON": "asserts"}), 573 ("--build-mode", {"[Dd][Ee][Bb][Uu][Gg]": "debug"}), 574 ] 575) 576 577if "darwin" == sys.platform: 578 cmd = ["sysctl", "hw.optional.fma"] 579 sysctl_cmd = subprocess.Popen(cmd, stdout=subprocess.PIPE) 580 581 # Non zero return, probably a permission issue 582 if sysctl_cmd.wait(): 583 print( 584 'Warning: sysctl exists but calling "{}" failed, defaulting to no fma3.'.format( 585 " ".join(cmd) 586 ) 587 ) 588 else: 589 result = sysctl_cmd.stdout.read().decode("ascii") 590 if "hw.optional.fma: 1" in result: 591 config.available_features.add("fma3") 592 593if not hasattr(sys, "getwindowsversion") or sys.getwindowsversion().build >= 17063: 594 config.available_features.add("unix-sockets") 595 596# .debug_frame is not emitted for targeting Windows x64, aarch64/arm64, AIX, or Apple Silicon Mac. 597if not re.match( 598 r"^(x86_64|aarch64|arm64|powerpc|powerpc64).*-(windows-gnu|windows-msvc|aix)", 599 config.target_triple, 600) and not re.match(r"^arm64(e)?-apple-(macos|darwin)", config.target_triple): 601 config.available_features.add("debug_frame") 602 603if config.enable_backtrace: 604 config.available_features.add("backtrace") 605 606if config.enable_threads: 607 config.available_features.add("thread_support") 608 609if config.have_libxml2: 610 config.available_features.add("libxml2") 611 612if config.have_curl: 613 config.available_features.add("curl") 614 615if config.have_httplib: 616 config.available_features.add("httplib") 617 618if config.have_opt_viewer_modules: 619 config.available_features.add("have_opt_viewer_modules") 620 621if config.expensive_checks: 622 config.available_features.add("expensive_checks") 623 624if "MemoryWithOrigins" in config.llvm_use_sanitizer: 625 config.available_features.add("use_msan_with_origins") 626 627 628# Some tools support an environment variable "OBJECT_MODE" on AIX OS, which 629# controls the kind of objects they will support. If there is no "OBJECT_MODE" 630# environment variable specified, the default behaviour is to support 32-bit 631# objects only. In order to not affect most test cases, which expect to support 632# 32-bit and 64-bit objects by default, set the environment variable 633# "OBJECT_MODE" to 'any' by default on AIX OS. 634if "system-aix" in config.available_features: 635 config.environment["OBJECT_MODE"] = "any" 636 637if config.has_logf128: 638 config.available_features.add("has_logf128") 639