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

Andrew Haberlandt via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 6 11:52:40 PST 2025


https://github.com/ndrewh created https://github.com/llvm/llvm-project/pull/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 enables runs builtins tests (even though the runtimes build has `COMPILER_RT_BUILD_BUILTINS=OFF`)


>From 31051e08869d5179c8fa114d65465d1d90d314de Mon Sep 17 00:00:00 2001
From: Andrew Haberlandt <ahaberlandt at apple.com>
Date: Wed, 5 Nov 2025 21:16:42 -0800
Subject: [PATCH] [compiler-rt] Add check-builtins target for
 LLVM_ENABLE_RUNTIMES-based build

---
 .../cmake/Modules/CompilerRTDarwinUtils.cmake |  1 +
 compiler-rt/lib/builtins/CMakeLists.txt       |  1 +
 compiler-rt/test/CMakeLists.txt               |  2 +-
 compiler-rt/test/builtins/CMakeLists.txt      | 26 ++++++++++++++---
 llvm/runtimes/CMakeLists.txt                  | 28 ++++++++++++++++++-
 5 files changed, 52 insertions(+), 6 deletions(-)

diff --git a/compiler-rt/cmake/Modules/CompilerRTDarwinUtils.cmake b/compiler-rt/cmake/Modules/CompilerRTDarwinUtils.cmake
index c6777bda9f0d1..7b679b2d27ae5 100644
--- a/compiler-rt/cmake/Modules/CompilerRTDarwinUtils.cmake
+++ b/compiler-rt/cmake/Modules/CompilerRTDarwinUtils.cmake
@@ -284,6 +284,7 @@ macro(darwin_add_builtin_library name suffix)
     ${ARGN})
   set(libname "${name}.${suffix}_${LIB_ARCH}_${LIB_OS}")
   add_library(${libname} STATIC ${LIB_SOURCES})
+  file(WRITE "${CMAKE_BINARY_DIR}/${libname}.sources.txt" "${LIB_SOURCES}")
   if(DARWIN_${LIB_OS}_SYSROOT)
     set(sysroot_flag -isysroot ${DARWIN_${LIB_OS}_SYSROOT})
   endif()
diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt
index 6c226aa7d2d48..bed3fabc4516d 100644
--- a/compiler-rt/lib/builtins/CMakeLists.txt
+++ b/compiler-rt/lib/builtins/CMakeLists.txt
@@ -976,6 +976,7 @@ else ()
                               C_STANDARD 11
                               CXX_STANDARD 17
                               PARENT_TARGET builtins)
+      file(WRITE "${CMAKE_BINARY_DIR}/clang_rt.builtins-${arch}.sources.txt" "${${arch}_SOURCES}")
       cmake_pop_check_state()
     endif ()
   endforeach ()
diff --git a/compiler-rt/test/CMakeLists.txt b/compiler-rt/test/CMakeLists.txt
index a2e4c8cbf5685..de40932787efc 100644
--- a/compiler-rt/test/CMakeLists.txt
+++ b/compiler-rt/test/CMakeLists.txt
@@ -66,7 +66,7 @@ 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)
+  if(COMPILER_RT_BUILD_BUILTINS OR COMPILER_RT_FORCE_TEST_BUILTINS_DIR)
     add_subdirectory(builtins)
   endif()
   if(COMPILER_RT_BUILD_SANITIZERS)
diff --git a/compiler-rt/test/builtins/CMakeLists.txt b/compiler-rt/test/builtins/CMakeLists.txt
index 63f4c94605c90..7001de1f26023 100644
--- a/compiler-rt/test/builtins/CMakeLists.txt
+++ b/compiler-rt/test/builtins/CMakeLists.txt
@@ -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_FORCE_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_FORCE_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.
@@ -79,10 +89,18 @@ 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_FORCE_TEST_BUILTINS_DIR to be set and contain a file named
+  # ${BUILTIN_LIB_TARGET_NAME}.sources.txt from the builtins build
+  if(NOT COMPILER_RT_FORCE_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_FORCE_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")
diff --git a/llvm/runtimes/CMakeLists.txt b/llvm/runtimes/CMakeLists.txt
index d877f0b883cc4..88fb323e5e449 100644
--- a/llvm/runtimes/CMakeLists.txt
+++ b/llvm/runtimes/CMakeLists.txt
@@ -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})



More information about the llvm-commits mailing list