[compiler-rt] Add check-builtins target for LLVM_ENABLE_RUNTIMES builds (#166837)

When doing a LLVM_ENABLE_RUNTIMES-based build of clang+compiler_rt, the
`check-builtins` target is missing and builtins tests are not run
(#112105, #144090).

This provides one possible path forward for enabling these tests.

The approach taken here is to test the builtins with the `compiler-rt`
runtime build (i.e. only if you pass
`LLVM_ENABLE_RUNTIMES='compiler-rt'`). The builtins tests currently rely
on shared test infrastructure in `compiler-rt/`, so this is probably the
easiest solution without relocating the builtins and their tests outside
of `compiler-rt/`.

The main challenge is that the built-ins test configuration expects to
be able to inspect the builtin target and see the sources used to build
it:
```
    get_target_property(BUILTIN_LIB_SOURCES "${BUILTIN_LIB_TARGET_NAME}" SOURCES)
```

Since the builtins build and runtimes build are separate under
LLVM_ENABLE_RUNTIMES, this target inspection is not possible. To get
around this, we write a temporary file alongside each builtins library
containing the list of sources (e.g.
`"${CMAKE_BINARY_DIR}/clang_rt.builtins-${arch}.sources.txt"`). Then, we
introduce an undocumented compiler-rt option
`COMPILER_RT_FORCE_TEST_BUILTINS_DIR` (which is only intended to be used
by the LLVM_ENABLE_RUNTIMES build, and could be removed after builtins
re relocated) that passes the path to the directory containing this
file, and configures builtins tests (even though the runtimes build has
`COMPILER_RT_BUILD_BUILTINS=OFF`)

rdar://163518748
This commit is contained in:
Andrew Haberlandt
2025-12-08 11:10:20 -08:00
committed by GitHub
parent fa511cde48
commit c5d17bdf0c
6 changed files with 70 additions and 9 deletions

View File

@@ -284,6 +284,11 @@ macro(darwin_add_builtin_library name suffix)
${ARGN})
set(libname "${name}.${suffix}_${LIB_ARCH}_${LIB_OS}")
add_library(${libname} STATIC ${LIB_SOURCES})
# Write out the sources that were used to compile the builtins so that tests can be run in
# an independent compiler-rt build (see: compiler-rt/test/builtins/CMakeLists.txt)
file(WRITE "${CMAKE_BINARY_DIR}/${libname}.sources.txt" "${LIB_SOURCES}")
if(DARWIN_${LIB_OS}_SYSROOT)
set(sysroot_flag -isysroot ${DARWIN_${LIB_OS}_SYSROOT})
endif()

View File

@@ -280,6 +280,14 @@ else()
# Architectures supported by compiler-rt libraries.
filter_available_targets(BUILTIN_SUPPORTED_ARCH
${ALL_BUILTIN_SUPPORTED_ARCH})
# COMPILER_RT_HAS_${arch}_* defines that are shared between lib/builtins/ and test/builtins/
foreach (arch ${BUILTIN_SUPPORTED_ARCH})
# NOTE: The corresponding check for if(APPLE) is in CompilerRTDarwinUtils.cmake
check_c_source_compiles("_Float16 foo(_Float16 x) { return x; }
int main(void) { return 0; }"
COMPILER_RT_HAS_${arch}_FLOAT16)
endforeach()
endif()
if(OS_NAME MATCHES "Linux|SerenityOS" AND NOT LLVM_USE_SANITIZER AND NOT

View File

@@ -990,9 +990,6 @@ else ()
endif()
endif()
endif()
check_c_source_compiles("_Float16 foo(_Float16 x) { return x; }
int main(void) { return 0; }"
COMPILER_RT_HAS_${arch}_FLOAT16)
append_list_if(COMPILER_RT_HAS_${arch}_FLOAT16 -DCOMPILER_RT_HAS_FLOAT16 BUILTIN_CFLAGS_${arch})
check_c_source_compiles("__bf16 foo(__bf16 x) { return x; }
int main(void) { return 0; }"
@@ -1028,6 +1025,9 @@ else ()
C_STANDARD 11
CXX_STANDARD 17
PARENT_TARGET builtins)
# Write out the sources that were used to compile the builtins so that tests can be run in
# an independent compiler-rt build (see: compiler-rt/test/builtins/CMakeLists.txt)
file(WRITE "${CMAKE_BINARY_DIR}/clang_rt.builtins-${arch}.sources.txt" "${${arch}_SOURCES}")
cmake_pop_check_state()
endif ()
endforeach ()

View File

@@ -73,7 +73,10 @@ endfunction()
# Run sanitizer tests only if we're sure that clang would produce
# working binaries.
if(COMPILER_RT_CAN_EXECUTE_TESTS)
if(COMPILER_RT_BUILD_BUILTINS)
# COMPILER_RT_TEST_BUILTINS_DIR allows running tests against builtins built
# in an independent build. This option is only indended to be used by
# LLVM_ENABLE_RUNTIMES-based builds.
if(COMPILER_RT_BUILD_BUILTINS OR COMPILER_RT_TEST_BUILTINS_DIR)
add_subdirectory(builtins)
endif()
if(COMPILER_RT_BUILD_SANITIZERS)

View File

@@ -1,6 +1,16 @@
set(BUILTINS_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(BUILTINS_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS} builtins)
# If COMPILER_RT_TEST_BUILTINS_DIR is set, the builtins
# were already built and we are just going to test them.
# NOTE: This is currently an LLVM-internal option which should
# only be used by the LLVM_ENABLE_RUNTIMES build configured
# in llvm/runtimes/CMakeLists.txt
if(COMPILER_RT_TEST_BUILTINS_DIR)
set(BUILTINS_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS})
else()
set(BUILTINS_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS} builtins)
endif()
set(BUILTINS_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/TestCases)
# Test cases.
@@ -84,10 +94,19 @@ foreach(arch ${BUILTIN_TEST_ARCH})
else()
set(BUILTIN_LIB_TARGET_NAME "clang_rt.builtins-${arch}")
endif()
if (NOT TARGET "${BUILTIN_LIB_TARGET_NAME}")
message(FATAL_ERROR "Target ${BUILTIN_LIB_TARGET_NAME} does not exist")
# Normally, we can just inspect the target directly to get the sources, but if
# we are testing an externally-built builtins library, we expect
# COMPILER_RT_TEST_BUILTINS_DIR to be set and contain a file named
# ${BUILTIN_LIB_TARGET_NAME}.sources.txt from the builtins build. This file
# is created by compiler-rt/lib/builtins/CMakeLists.txt
if(NOT COMPILER_RT_TEST_BUILTINS_DIR)
if (NOT TARGET "${BUILTIN_LIB_TARGET_NAME}")
message(FATAL_ERROR "Target ${BUILTIN_LIB_TARGET_NAME} does not exist")
endif()
get_target_property(BUILTIN_LIB_SOURCES "${BUILTIN_LIB_TARGET_NAME}" SOURCES)
else()
file(READ "${COMPILER_RT_TEST_BUILTINS_DIR}/${BUILTIN_LIB_TARGET_NAME}.sources.txt" BUILTIN_LIB_SOURCES)
endif()
get_target_property(BUILTIN_LIB_SOURCES "${BUILTIN_LIB_TARGET_NAME}" SOURCES)
list(LENGTH BUILTIN_LIB_SOURCES BUILTIN_LIB_SOURCES_LENGTH)
if (BUILTIN_LIB_SOURCES_LENGTH EQUAL 0)
message(FATAL_ERROR "Failed to find source files for ${arch} builtin library")

View File

@@ -255,7 +255,10 @@ function(runtime_default_target)
if(LLVM_INCLUDE_TESTS)
set_property(GLOBAL APPEND PROPERTY LLVM_ALL_LIT_TESTSUITES "@${LLVM_BINARY_DIR}/runtimes/runtimes-bins/lit.tests")
list(APPEND test_targets runtimes-test-depends check-runtimes)
list(APPEND test_targets runtimes-test-depends check-runtimes check-builtins)
# The default runtimes target can run tests the default builtins target
list(APPEND ARG_CMAKE_ARGS "-DCOMPILER_RT_FORCE_TEST_BUILTINS_DIR=${LLVM_BINARY_DIR}/runtimes/builtins-bins/")
endif()
set_enable_per_target_runtime_dir()
@@ -362,6 +365,15 @@ function(runtime_register_target name)
list(APPEND ${name}_test_targets ${target}-${name})
list(APPEND test_targets ${target}-${name})
endforeach()
# If a builtins-${name} target exists, we'll test those builtins
# with this runtimes build
if(TARGET builtins-${name})
list(APPEND ARG_CMAKE_ARGS "-DCOMPILER_RT_FORCE_TEST_BUILTINS_DIR=${LLVM_BINARY_DIR}/runtimes/builtins-${name}-bins/")
set(check-builtins-${name} check-builtins)
list(APPEND ${name}_test_targets check-builtins-${name})
list(APPEND test_targets check-builtins-${name})
endif()
set(test_targets "${test_targets}" PARENT_SCOPE)
endif()
@@ -427,6 +439,9 @@ function(runtime_register_target name)
if(LLVM_INCLUDE_TESTS)
add_dependencies(check-runtimes check-runtimes-${name})
add_dependencies(runtimes-test-depends runtimes-test-depends-${name})
if(TARGET builtins-${name})
add_dependencies(check-builtins check-builtins-${name})
endif()
endif()
foreach(runtime_name ${runtime_names})
if(NOT TARGET ${runtime_name})
@@ -602,6 +617,17 @@ if(build_runtimes)
PROPERTIES FOLDER "Runtimes"
)
set(test_targets "")
# NOTE: Currently, the builtins tests are run with the runtimes build,
# and the default runtimes target installs a check-builtins target
# which forwards to the default builtins build. If the default runtimes
# target is not used, we create a custom target which will depend on
# each check-builtins-${name}.
add_custom_target(check-builtins)
set_target_properties(
check-builtins
PROPERTIES FOLDER "Compiler-RT"
)
endif()
if(LLVM_RUNTIME_DISTRIBUTION_COMPONENTS)
foreach(component ${LLVM_RUNTIME_DISTRIBUTION_COMPONENTS})