[libc-commits] [libc] a3da102 - [libc] Use llvm-link approach to create libc bitcode library for GPU targets (#210662)

via libc-commits libc-commits at lists.llvm.org
Sun Aug 2 02:52:50 PDT 2026


Author: jinge90
Date: 2026-08-02T02:52:44-07:00
New Revision: a3da10236c52f4cf05936790a7ebc6e8f12b34ba

URL: https://github.com/llvm/llvm-project/commit/a3da10236c52f4cf05936790a7ebc6e8f12b34ba
DIFF: https://github.com/llvm/llvm-project/commit/a3da10236c52f4cf05936790a7ebc6e8f12b34ba.diff

LOG: [libc] Use llvm-link approach to create libc bitcode library for GPU targets (#210662)

Added: 
    

Modified: 
    libc/CMakeLists.txt
    libc/cmake/caches/gpu.cmake
    libc/cmake/modules/LLVMLibCLibraryRules.cmake
    libc/lib/CMakeLists.txt
    libc/startup/gpu/CMakeLists.txt
    llvm/runtimes/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/libc/CMakeLists.txt b/libc/CMakeLists.txt
index 3aa975ba51416..c5dea3100f053 100644
--- a/libc/CMakeLists.txt
+++ b/libc/CMakeLists.txt
@@ -293,6 +293,10 @@ endif()
 if(LIBC_TARGET_OS_IS_GPU)
   include(prepare_libc_gpu_build)
   set(LIBC_ENABLE_UNITTESTS OFF)
+  find_program(LIBC_LLVM_LINK llvm-link HINTS ${LLVM_TOOLS_BINARY_DIR})
+  if(NOT LIBC_LLVM_LINK)
+    message(FATAL_ERROR "llvm-link not found in ${LLVM_TOOLS_BINARY_DIR} or system path")
+  endif()
 elseif(LIBC_TARGET_OS_IS_BAREMETAL)
   set(LIBC_ENABLE_UNITTESTS OFF)
 endif()

diff  --git a/libc/cmake/caches/gpu.cmake b/libc/cmake/caches/gpu.cmake
index 1867db9ffa12e..ee61c34cf9a67 100644
--- a/libc/cmake/caches/gpu.cmake
+++ b/libc/cmake/caches/gpu.cmake
@@ -1,4 +1,4 @@
 set(LLVM_ENABLE_PROJECTS "clang;clang-tools-extra;lld" CACHE STRING "")
-set(LLVM_RUNTIME_TARGETS default;amdgcn-amd-amdhsa;nvptx64-nvidia-cuda CACHE STRING "") 
+set(LLVM_RUNTIME_TARGETS default;amdgcn-amd-amdhsa;nvptx64-nvidia-cuda CACHE STRING "")
 set(RUNTIMES_nvptx64-nvidia-cuda_LLVM_ENABLE_RUNTIMES "compiler-rt;libc" CACHE STRING "")
 set(RUNTIMES_amdgcn-amd-amdhsa_LLVM_ENABLE_RUNTIMES "compiler-rt;libc" CACHE STRING "")

diff  --git a/libc/cmake/modules/LLVMLibCLibraryRules.cmake b/libc/cmake/modules/LLVMLibCLibraryRules.cmake
index 2df8f49100b99..a90877dfb2746 100644
--- a/libc/cmake/modules/LLVMLibCLibraryRules.cmake
+++ b/libc/cmake/modules/LLVMLibCLibraryRules.cmake
@@ -80,43 +80,48 @@ function(get_all_object_file_deps result fq_deps_list)
   set(${result} ${all_deps} PARENT_SCOPE)
 endfunction()
 
+# Link bitcode inputs into a single LLVM IR module using llvm-link. Build
+# static archive library firstly and use this static archive library as
+# as llvm-link's input.
+# Usage:
+#     llvm_link_bitcode(
+#       target_name
+#       OUTPUT <output file path>
+#       INPUTS <input file path>
+#       DEPENDS <targets that must be built first>
+#     )
+function(llvm_link_bitcode target_name)
+  cmake_parse_arguments(
+    "ARG"
+    ""
+    "OUTPUT"
+    "INPUTS;DEPENDS"
+    ${ARGN}
+  )
+  add_custom_command(
+    OUTPUT ${ARG_OUTPUT}
+    COMMAND ${LIBC_LLVM_LINK} ${ARG_INPUTS} -o ${ARG_OUTPUT}
+    DEPENDS ${ARG_DEPENDS}
+    COMMENT "Linking bitcode ${ARG_OUTPUT}"
+  )
+  add_custom_target(${target_name} ALL DEPENDS ${ARG_OUTPUT})
+  set_target_properties(${target_name} PROPERTIES TARGET_FILE ${ARG_OUTPUT})
+endfunction(llvm_link_bitcode)
+
 # A rule to build a library from a collection of entrypoint objects and bundle
-# it in a single LLVM-IR bitcode file.
+# it in a single LLVM IR module.
 # Usage:
 #     add_bitcode_entrypoint_library(
+#       target_name
+#       base_target_name
 #       DEPENDS <list of add_entrypoint_object targets>
 #     )
 function(add_bitcode_entrypoint_library target_name base_target_name)
-  cmake_parse_arguments(
-    "ENTRYPOINT_LIBRARY"
-    "" # No optional arguments
-    "" # No single value arguments
-    "DEPENDS" # Multi-value arguments
-    ${ARGN}
+  llvm_link_bitcode(${target_name}
+    OUTPUT ${LIBC_LIBRARY_DIR}/${target_name}.bc
+    INPUTS $<TARGET_FILE:${base_target_name}>
+    DEPENDS ${base_target_name}
   )
-  if(NOT ENTRYPOINT_LIBRARY_DEPENDS)
-    message(FATAL_ERROR "'add_entrypoint_library' target requires a DEPENDS list "
-                        "of 'add_entrypoint_object' targets.")
-  endif()
-
-  get_fq_deps_list(fq_deps_list ${ENTRYPOINT_LIBRARY_DEPENDS})
-  get_all_object_file_deps(all_deps "${fq_deps_list}")
-
-  set(objects "")
-  foreach(dep IN LISTS all_deps)
-    set(object $<$<STREQUAL:$<TARGET_NAME_IF_EXISTS:${dep}>,${dep}>:$<TARGET_OBJECTS:${dep}>>)
-    list(APPEND objects ${object})
-  endforeach()
-
-  add_executable(${target_name} ${objects})
-  if(LIBC_TARGET_ARCHITECTURE_IS_SPIRV)
-      target_link_options(${target_name} PRIVATE "${LIBC_COMPILE_OPTIONS_DEFAULT}"
-                      "-nostdlib" "-emit-llvm")
-  else()  
-      target_link_options(${target_name} PRIVATE "${LIBC_COMPILE_OPTIONS_DEFAULT}"
-                      "-r" "-nostdlib" "-flto" "-Wl,--lto-emit-llvm")
-  endif()
-  add_dependencies(${base_target_name} ${target_name})
 endfunction(add_bitcode_entrypoint_library)
 
 # A rule to build a library from a collection of entrypoint objects.

diff  --git a/libc/lib/CMakeLists.txt b/libc/lib/CMakeLists.txt
index 8ef0329471521..a12c020a2aae8 100644
--- a/libc/lib/CMakeLists.txt
+++ b/libc/lib/CMakeLists.txt
@@ -63,7 +63,7 @@ install(
 )
 
 foreach(file ${added_bitcode_targets})
-  install(FILES $<TARGET_FILE:${file}>
+  install(FILES $<TARGET_PROPERTY:${file},TARGET_FILE>
           DESTINATION ${LIBC_INSTALL_LIBRARY_DIR}
           RENAME $<TARGET_PROPERTY:${file},OUTPUT_NAME>
           COMPONENT libc

diff  --git a/libc/startup/gpu/CMakeLists.txt b/libc/startup/gpu/CMakeLists.txt
index 12cb891a687d8..7744bbbb595c1 100644
--- a/libc/startup/gpu/CMakeLists.txt
+++ b/libc/startup/gpu/CMakeLists.txt
@@ -27,15 +27,13 @@ function(add_startup_object name)
       OUTPUT_NAME ${name}.o
   )
 
-  # Make an executable target of relocatable bitcode for clang if needed.
+  # Make a relocatable bitcode object for clang if needed.
   if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR)
-    add_executable(${fq_target_name}.exe $<TARGET_OBJECTS:${fq_target_name}>)
-    set_target_properties(${fq_target_name}.exe PROPERTIES
-      RUNTIME_OUTPUT_DIRECTORY ${LIBC_LIBRARY_DIR}
-      RUNTIME_OUTPUT_NAME ${name}.o)
-    target_link_options(${fq_target_name}.exe PRIVATE
-                        ${LIBC_COMPILE_OPTIONS_DEFAULT}
-                        "-r" "-nostdlib" "-flto" "-Wl,--lto-emit-llvm")
+    llvm_link_bitcode(${fq_target_name}.exe
+      OUTPUT ${LIBC_LIBRARY_DIR}/${name}.o
+      INPUTS $<TARGET_OBJECTS:${fq_target_name}>
+      DEPENDS ${fq_target_name}
+    )
   endif()
 endfunction()
 

diff  --git a/llvm/runtimes/CMakeLists.txt b/llvm/runtimes/CMakeLists.txt
index 02d58618299a1..f5477c3d6ae8a 100644
--- a/llvm/runtimes/CMakeLists.txt
+++ b/llvm/runtimes/CMakeLists.txt
@@ -653,6 +653,9 @@ if(build_runtimes)
       if(TARGET clang-nvlink-wrapper)
         list(APPEND extra_deps clang-nvlink-wrapper)
       endif()
+      if(TARGET llvm-link)
+        list(APPEND extra_deps llvm-link)
+      endif()
     endif()
   endforeach()
   if(LLVM_LIBC_FULL_BUILD)


        


More information about the libc-commits mailing list