https://github.com/jhuber6 updated 
https://github.com/llvm/llvm-project/pull/197034

>From 727d1382dcc4cd145433347bd500741da1743f90 Mon Sep 17 00:00:00 2001
From: Joseph Huber <[email protected]>
Date: Mon, 11 May 2026 15:50:39 -0500
Subject: [PATCH 1/4] [libclc] Base the build around `add_sources` instead of
 source list

Summary:
The current build uses a curated + deduplicated source list. This PR
seeks to simplify this a little bit and canonicalize the behavior.

Now we create the target up-front, `clc` and `opencl`. We add the
directories which add sources to this target. We normalize the
architecture to the variants. We always add target specific versions
first. When we add sources we check if the file already exists and defer
to the architecture specific one.

This normalized the behavior, the directories are now laid out like this
`clc/<arch>/<os>`. We normalize these to `amdgpu`, `nvptx`, and `spirv`
respectively. We use the OS for the newly created vulkan target. We now
control variants via checking if the directory for that exists, so it's
nested more naturally.

Hopefully this makes more sense, the goal is to exercise the fact that
we have individual builds now. Previously this did not work because you
could not add_subdirectory more than once.
---
 libclc/CMakeLists.txt                         | 137 +++++++----------
 libclc/clc/CMakeLists.txt                     |   4 +
 libclc/clc/lib/amdgpu/CMakeLists.txt          |   8 +-
 libclc/clc/lib/generic/CMakeLists.txt         |  13 +-
 .../{ptx-nvidiacl => nvptx}/CMakeLists.txt    |   3 +-
 .../{ptx-nvidiacl => nvptx}/math/clc_log.cl   |   0
 .../{ptx-nvidiacl => nvptx}/math/clc_rsqrt.cl |   0
 .../{ptx-nvidiacl => nvptx}/math/clc_sinpi.cl |   0
 .../{ptx-nvidiacl => nvptx}/math/clc_sqrt.cl  |   0
 .../relational/clc_isinf.cl                   |   0
 .../synchronization/clc_work_group_barrier.cl |   0
 .../workitem/clc_get_global_id.cl             |   0
 .../workitem/clc_get_global_size.cl           |   0
 .../workitem/clc_get_group_id.cl              |   0
 .../workitem/clc_get_local_id.cl              |   0
 .../workitem/clc_get_local_size.cl            |   0
 .../workitem/clc_get_max_sub_group_size.cl    |   0
 .../workitem/clc_get_num_groups.cl            |   0
 .../workitem/clc_get_sub_group_local_id.cl    |   0
 libclc/clc/lib/spirv/CMakeLists.txt           |   7 +-
 libclc/clc/lib/spirv/vulkan/CMakeLists.txt    |   4 +
 .../{ => spirv}/vulkan/integer/clc_mul_hi.cl  |   0
 .../lib/{ => spirv}/vulkan/math/clc_sw_fma.cl |   0
 libclc/clc/lib/vulkan/CMakeLists.txt          |   5 -
 libclc/cmake/modules/AddLibclc.cmake          | 143 ++++++++----------
 libclc/opencl/CMakeLists.txt                  |   6 +
 libclc/opencl/lib/amdgpu/CMakeLists.txt       |   3 +-
 libclc/opencl/lib/generic/CMakeLists.txt      |   5 +-
 libclc/opencl/lib/spirv/CMakeLists.txt        |  12 +-
 .../lib/{ => spirv}/vulkan/CMakeLists.txt     |  11 +-
 .../vulkan/conversion/convert_float.inc       |   0
 .../vulkan/conversion/convert_float2float.cl  |   0
 .../vulkan/conversion/convert_float2int.cl    |   0
 .../vulkan/conversion/convert_int2float.cl    |   0
 .../vulkan/conversion/convert_integer.cl      |   0
 .../vulkan/conversion/convert_integer.inc     |   0
 .../opencl/lib/{ => spirv}/vulkan/math/fma.cl |   0
 .../{ => spirv}/vulkan/shared/vstore_half.cl  |   0
 .../{ => spirv}/vulkan/shared/vstore_half.inc |   0
 39 files changed, 165 insertions(+), 196 deletions(-)
 create mode 100644 libclc/clc/CMakeLists.txt
 rename libclc/clc/lib/{ptx-nvidiacl => nvptx}/CMakeLists.txt (83%)
 rename libclc/clc/lib/{ptx-nvidiacl => nvptx}/math/clc_log.cl (100%)
 rename libclc/clc/lib/{ptx-nvidiacl => nvptx}/math/clc_rsqrt.cl (100%)
 rename libclc/clc/lib/{ptx-nvidiacl => nvptx}/math/clc_sinpi.cl (100%)
 rename libclc/clc/lib/{ptx-nvidiacl => nvptx}/math/clc_sqrt.cl (100%)
 rename libclc/clc/lib/{ptx-nvidiacl => nvptx}/relational/clc_isinf.cl (100%)
 rename libclc/clc/lib/{ptx-nvidiacl => 
nvptx}/synchronization/clc_work_group_barrier.cl (100%)
 rename libclc/clc/lib/{ptx-nvidiacl => nvptx}/workitem/clc_get_global_id.cl 
(100%)
 rename libclc/clc/lib/{ptx-nvidiacl => nvptx}/workitem/clc_get_global_size.cl 
(100%)
 rename libclc/clc/lib/{ptx-nvidiacl => nvptx}/workitem/clc_get_group_id.cl 
(100%)
 rename libclc/clc/lib/{ptx-nvidiacl => nvptx}/workitem/clc_get_local_id.cl 
(100%)
 rename libclc/clc/lib/{ptx-nvidiacl => nvptx}/workitem/clc_get_local_size.cl 
(100%)
 rename libclc/clc/lib/{ptx-nvidiacl => 
nvptx}/workitem/clc_get_max_sub_group_size.cl (100%)
 rename libclc/clc/lib/{ptx-nvidiacl => nvptx}/workitem/clc_get_num_groups.cl 
(100%)
 rename libclc/clc/lib/{ptx-nvidiacl => 
nvptx}/workitem/clc_get_sub_group_local_id.cl (100%)
 create mode 100644 libclc/clc/lib/spirv/vulkan/CMakeLists.txt
 rename libclc/clc/lib/{ => spirv}/vulkan/integer/clc_mul_hi.cl (100%)
 rename libclc/clc/lib/{ => spirv}/vulkan/math/clc_sw_fma.cl (100%)
 delete mode 100644 libclc/clc/lib/vulkan/CMakeLists.txt
 create mode 100644 libclc/opencl/CMakeLists.txt
 rename libclc/opencl/lib/{ => spirv}/vulkan/CMakeLists.txt (85%)
 rename libclc/opencl/lib/{ => spirv}/vulkan/conversion/convert_float.inc (100%)
 rename libclc/opencl/lib/{ => spirv}/vulkan/conversion/convert_float2float.cl 
(100%)
 rename libclc/opencl/lib/{ => spirv}/vulkan/conversion/convert_float2int.cl 
(100%)
 rename libclc/opencl/lib/{ => spirv}/vulkan/conversion/convert_int2float.cl 
(100%)
 rename libclc/opencl/lib/{ => spirv}/vulkan/conversion/convert_integer.cl 
(100%)
 rename libclc/opencl/lib/{ => spirv}/vulkan/conversion/convert_integer.inc 
(100%)
 rename libclc/opencl/lib/{ => spirv}/vulkan/math/fma.cl (100%)
 rename libclc/opencl/lib/{ => spirv}/vulkan/shared/vstore_half.cl (100%)
 rename libclc/opencl/lib/{ => spirv}/vulkan/shared/vstore_half.inc (100%)

diff --git a/libclc/CMakeLists.txt b/libclc/CMakeLists.txt
index 3f84458336950..55f2d85dcdf51 100644
--- a/libclc/CMakeLists.txt
+++ b/libclc/CMakeLists.txt
@@ -24,8 +24,8 @@ option(
 
 # List of all supported architectures.
 set( LIBCLC_ARCHS_ALL amdgpu amdgcn nvptx64 )
-set( LIBCLC_ARCHS_SPIRV spirv spirv32 spirv64)
-list( APPEND LIBCLC_ARCHS_ALL ${LIBCLC_ARCHS_SPIRV})
+set( LIBCLC_ARCHS_SPIRV spirv spirv32 spirv64 )
+list( APPEND LIBCLC_ARCHS_ALL ${LIBCLC_ARCHS_SPIRV} )
 
 set(LIBCLC_TARGET ${LLVM_DEFAULT_TARGET_TRIPLE})
 
@@ -33,10 +33,13 @@ if(NOT LIBCLC_TARGET)
   message(FATAL_ERROR "libclc target is empty\n")
 endif()
 
-string( REPLACE "-" ";" _target_components ${LIBCLC_TARGET} )
-list(GET _target_components 0 _target_arch)
-if(NOT "${_target_arch}" IN_LIST LIBCLC_ARCHS_ALL)
-  message(FATAL_ERROR "Unknown libclc target architecture: ${_target_arch}\n"
+# Parse the target triple into arch and OS components.
+string(REPLACE "-" ";" triple_components ${LIBCLC_TARGET})
+list(GET triple_components 0 LIBCLC_TARGET_ARCH)
+list(GET triple_components 2 LIBCLC_TARGET_OS)
+
+if(NOT "${LIBCLC_TARGET_ARCH}" IN_LIST LIBCLC_ARCHS_ALL)
+  message(FATAL_ERROR "Unknown libclc target architecture: 
${LIBCLC_TARGET_ARCH}\n"
     "Target was: ${LIBCLC_TARGET}\n"
     "Valid architectures are: ${LIBCLC_ARCHS_ALL}\n")
 endif()
@@ -98,12 +101,17 @@ endif()
 
 message(STATUS "libclc target '${LIBCLC_TARGET}' is enabled")
 
-string( REPLACE "-" ";" TRIPLE  ${LIBCLC_TARGET} )
-list(GET TRIPLE 0 ARCH)
-list(GET TRIPLE 2 OS)
+# Map the LLVM target architecture to the standard directory name.
+if(LIBCLC_TARGET_ARCH STREQUAL amdgcn OR LIBCLC_TARGET_ARCH STREQUAL amdgpu)
+  set(LIBCLC_ARCH_DIR amdgpu)
+elseif(LIBCLC_TARGET_ARCH STREQUAL nvptx64)
+  set(LIBCLC_ARCH_DIR nvptx)
+elseif(LIBCLC_TARGET_ARCH IN_LIST LIBCLC_ARCHS_SPIRV)
+  set(LIBCLC_ARCH_DIR spirv)
+endif()
 
-if(ARCH IN_LIST LIBCLC_ARCHS_SPIRV)
-  if(NOT OS STREQUAL vulkan AND NOT LIBCLC_USE_SPIRV_BACKEND AND NOT 
llvm-spirv_exe)
+if(LIBCLC_TARGET_ARCH IN_LIST LIBCLC_ARCHS_SPIRV)
+  if(NOT LIBCLC_TARGET_OS STREQUAL vulkan AND NOT LIBCLC_USE_SPIRV_BACKEND AND 
NOT llvm-spirv_exe)
     message(FATAL_ERROR "SPIR-V backend or llvm-spirv is required for libclc 
${LIBCLC_TARGET}")
   endif()
 endif()
@@ -114,23 +122,16 @@ foreach( tool IN ITEMS opt llvm-link )
   endif()
 endforeach()
 
-add_subdirectory(clc/lib/generic)
-add_subdirectory(opencl/lib/generic)
-
-if(ARCH STREQUAL amdgcn)
-  add_subdirectory(clc/lib/amdgpu)
-  add_subdirectory(opencl/lib/amdgpu)
-elseif(ARCH STREQUAL nvptx64)
-  add_subdirectory(clc/lib/ptx-nvidiacl)
-elseif(ARCH STREQUAL spirv OR ARCH STREQUAL spirv32 OR ARCH STREQUAL spirv64)
-  if(OS STREQUAL vulkan)
-    add_subdirectory(clc/lib/vulkan)
-    add_subdirectory(opencl/lib/vulkan)
-  else()
-    add_subdirectory(clc/lib/spirv)
-    add_subdirectory(opencl/lib/spirv)
-  endif()
-endif()
+# Create library targets before add_subdirectory calls so that
+# subdirectories can add sources via libclc_add_sources().
+set(LIBCLC_CLC_TARGET clc)
+add_library(${LIBCLC_CLC_TARGET} STATIC)
+
+set(LIBCLC_OPENCL_TARGET opencl)
+add_library(${LIBCLC_OPENCL_TARGET} STATIC)
+
+add_subdirectory(clc)
+add_subdirectory(opencl)
 
 add_custom_target( libclc ALL )
 
@@ -140,9 +141,9 @@ add_dependencies( libclc libclc-opencl-builtins )
 # Determine the clang target triple. Vulkan and SPIR-V backend targets use the
 # triple directly; other SPIR-V targets fall back to the legacy SPIR target.
 set(clang_triple ${LIBCLC_TARGET})
-if(ARCH IN_LIST LIBCLC_ARCHS_SPIRV)
-  if(NOT OS STREQUAL vulkan AND NOT LIBCLC_USE_SPIRV_BACKEND)
-    if(ARCH STREQUAL spirv)
+if(LIBCLC_TARGET_ARCH IN_LIST LIBCLC_ARCHS_SPIRV)
+  if(NOT LIBCLC_TARGET_OS STREQUAL vulkan AND NOT LIBCLC_USE_SPIRV_BACKEND)
+    if(LIBCLC_TARGET_ARCH STREQUAL spirv)
       set(clang_triple spir--)
     else()
       set(clang_triple spir64--)
@@ -153,10 +154,10 @@ endif()
 # Address space values.
 set(private_addrspace_val 0)
 set(generic_addrspace_val 0)
-if(ARCH STREQUAL amdgcn)
+if(LIBCLC_TARGET_ARCH STREQUAL amdgcn)
   set(private_addrspace_val 5)
 endif()
-if(ARCH IN_LIST LIBCLC_ARCHS_SPIRV AND NOT OS STREQUAL vulkan)
+if(LIBCLC_TARGET_ARCH IN_LIST LIBCLC_ARCHS_SPIRV AND NOT LIBCLC_TARGET_OS 
STREQUAL vulkan)
   set(generic_addrspace_val 4)
 endif()
 
@@ -165,50 +166,18 @@ set(target_compile_flags)
 set(target_extra_defines)
 set(opt_flags -O3)
 
-if(ARCH IN_LIST LIBCLC_ARCHS_SPIRV)
-  if(OS STREQUAL vulkan)
+if(LIBCLC_TARGET_ARCH IN_LIST LIBCLC_ARCHS_SPIRV)
+  if(LIBCLC_TARGET_OS STREQUAL vulkan)
     list(APPEND target_compile_flags -Wno-unknown-assumption 
-U__opencl_c_int64)
   else()
     list(APPEND target_compile_flags -O0 -finline-hint-functions)
     list(APPEND target_extra_defines CLC_SPIRV)
     set(opt_flags)
   endif()
-elseif(ARCH STREQUAL amdgcn)
+elseif(LIBCLC_TARGET_ARCH STREQUAL amdgcn)
   list(APPEND target_compile_flags "SHELL:-Xclang -mcode-object-version=none")
 endif()
 
-# Collect CLC sources; target-specific sources override generic ones by 
basename.
-set(_clc_overrides)
-if(ARCH STREQUAL amdgcn)
-  list(APPEND _clc_overrides ${CLC_AMDGPU_SOURCES})
-elseif(ARCH STREQUAL nvptx64 AND (OS STREQUAL nvidiacl OR OS STREQUAL cuda))
-  list(APPEND _clc_overrides ${CLC_PTX_NVIDIACL_SOURCES})
-elseif(ARCH IN_LIST LIBCLC_ARCHS_SPIRV)
-  if(OS STREQUAL vulkan)
-    list(APPEND _clc_overrides ${CLC_VULKAN_SOURCES})
-  else()
-    list(APPEND _clc_overrides ${CLC_SPIRV_SOURCES})
-  endif()
-endif()
-libclc_merge_sources(clc_sources ${CLC_GENERIC_SOURCES} ${_clc_overrides})
-
-# Collect OpenCL sources. SPIR-V and Vulkan targets use self-contained
-# subsets while others merge with target-specific overrides.
-if(ARCH IN_LIST LIBCLC_ARCHS_SPIRV)
-  if(OS STREQUAL vulkan)
-    set(opencl_sources ${OPENCL_VULKAN_SOURCES})
-  else()
-    set(opencl_sources ${OPENCL_SPIRV_SOURCES})
-  endif()
-else()
-  set(_opencl_overrides)
-  if(ARCH STREQUAL amdgcn)
-    list(APPEND _opencl_overrides ${OPENCL_AMDGCN_SOURCES})
-  endif()
-  libclc_merge_sources(opencl_sources
-    ${OPENCL_GENERIC_SOURCES} ${_opencl_overrides})
-endif()
-
 # Common compile options shared by CLC and OpenCL libraries.
 set(compile_flags
   -flto
@@ -227,35 +196,37 @@ set(compile_flags
   ${target_compile_flags}
 )
 
-set(_common_defs
+set(common_defs
   ${target_extra_defines}
   __CLC_PRIVATE_ADDRSPACE_VAL=${private_addrspace_val}
   __CLC_GENERIC_ADDRSPACE_VAL=${generic_addrspace_val}
 )
 
-# Build the CLC internal builtins library.
-string(REPLACE "-" "_" lib_suffix ${LIBCLC_TARGET})
-set(clc_lib clc_builtins_${lib_suffix})
-add_libclc_builtin_library(${clc_lib}
-  SOURCES ${clc_sources}
+# Configure the CLC internal builtins library.
+libclc_configure_library(${LIBCLC_CLC_TARGET}
   COMPILE_OPTIONS ${compile_flags}
   INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/clc/include
-  COMPILE_DEFINITIONS ${_common_defs}
+  COMPILE_DEFINITIONS ${common_defs}
   FOLDER "libclc/Device IR/CLC"
 )
 
-# Build, link, and install the final OpenCL builtins library.
-add_libclc_library(libclc-${LIBCLC_TARGET}
-  ARCH ${ARCH}
-  TRIPLE ${clang_triple}
-  TARGET_TRIPLE ${LIBCLC_TARGET}
-  SOURCES ${opencl_sources}
+# Configure the OpenCL builtins library.
+libclc_configure_library(${LIBCLC_OPENCL_TARGET}
   COMPILE_OPTIONS ${compile_flags} "SHELL:-Xclang -fdeclare-opencl-builtins"
   INCLUDE_DIRS
     ${CMAKE_CURRENT_SOURCE_DIR}/clc/include
     ${CMAKE_CURRENT_SOURCE_DIR}/opencl/include
-  COMPILE_DEFINITIONS ${_common_defs}
-  INTERNALIZE_LIBRARIES ${clc_lib}
+  COMPILE_DEFINITIONS ${common_defs}
+  FOLDER "libclc/Device IR/Intermediate"
+)
+
+# Link and install the final OpenCL builtins library.
+libclc_add_library(libclc-${LIBCLC_TARGET}
+  ARCH ${LIBCLC_TARGET_ARCH}
+  TRIPLE ${clang_triple}
+  TARGET_TRIPLE ${LIBCLC_TARGET}
+  LIBRARIES ${LIBCLC_OPENCL_TARGET}
+  INTERNALIZE_LIBRARIES ${LIBCLC_CLC_TARGET}
   OPT_FLAGS ${opt_flags}
   OUTPUT_FILENAME libclc
   PARENT_TARGET libclc-opencl-builtins
diff --git a/libclc/clc/CMakeLists.txt b/libclc/clc/CMakeLists.txt
new file mode 100644
index 0000000000000..bcec1bf9406ab
--- /dev/null
+++ b/libclc/clc/CMakeLists.txt
@@ -0,0 +1,4 @@
+if(LIBCLC_ARCH_DIR AND EXISTS 
${CMAKE_CURRENT_SOURCE_DIR}/lib/${LIBCLC_ARCH_DIR})
+  add_subdirectory(lib/${LIBCLC_ARCH_DIR})
+endif()
+add_subdirectory(lib/generic)
diff --git a/libclc/clc/lib/amdgpu/CMakeLists.txt 
b/libclc/clc/lib/amdgpu/CMakeLists.txt
index a5cd47fab4462..cdeadbd3b9373 100644
--- a/libclc/clc/lib/amdgpu/CMakeLists.txt
+++ b/libclc/clc/lib/amdgpu/CMakeLists.txt
@@ -1,5 +1,4 @@
-libclc_configure_source_list(CLC_AMDGPU_SOURCES
-  ${CMAKE_CURRENT_SOURCE_DIR}
+libclc_add_sources(${LIBCLC_CLC_TARGET}
   address_space/clc_qualifier.cl
   math/clc_cbrt.cl
   math/clc_exp.cl
@@ -45,9 +44,10 @@ libclc_configure_source_list(CLC_AMDGPU_SOURCES
   workitem/clc_get_num_sub_groups.cl
   workitem/clc_get_sub_group_id.cl
   workitem/clc_get_sub_group_size.cl
-  workitem/clc_get_work_dim.cl)
+  workitem/clc_get_work_dim.cl
+)
 
-libclc_configure_source_options(${CMAKE_CURRENT_SOURCE_DIR} -fapprox-func
+libclc_set_source_options(-fapprox-func
   math/clc_native_exp.cl
   math/clc_native_exp2.cl
   math/clc_native_log10.cl
diff --git a/libclc/clc/lib/generic/CMakeLists.txt 
b/libclc/clc/lib/generic/CMakeLists.txt
index 168a0f1ff1e84..8124e9471ffb7 100644
--- a/libclc/clc/lib/generic/CMakeLists.txt
+++ b/libclc/clc/lib/generic/CMakeLists.txt
@@ -1,5 +1,4 @@
-libclc_configure_source_list(CLC_GENERIC_SOURCES
-  ${CMAKE_CURRENT_SOURCE_DIR}
+libclc_add_sources(${LIBCLC_CLC_TARGET}
   async/clc_prefetch.cl
   atomic/clc_atomic_compare_exchange.cl
   atomic/clc_atomic_dec.cl
@@ -209,7 +208,7 @@ libclc_configure_source_list(CLC_GENERIC_SOURCES
   workitem/clc_get_sub_group_size.cl
 )
 
-libclc_configure_source_options(${CMAKE_CURRENT_SOURCE_DIR} -fapprox-func
+libclc_set_source_options(-fapprox-func
   math/clc_native_cos.cl
   math/clc_native_divide.cl
   math/clc_native_exp.cl
@@ -226,8 +225,10 @@ 
libclc_configure_source_options(${CMAKE_CURRENT_SOURCE_DIR} -fapprox-func
   math/clc_native_tan.cl
   math/clc_div_fast.cl
   math/clc_recip_fast.cl
-  math/clc_sqrt_fast.cl)
+  math/clc_sqrt_fast.cl
+)
 
-libclc_configure_source_options(${CMAKE_CURRENT_SOURCE_DIR} 
-cl-fp32-correctly-rounded-divide-sqrt
+libclc_set_source_options(-cl-fp32-correctly-rounded-divide-sqrt
   math/clc_div_cr.cl
-  math/clc_sqrt_cr.cl)
+  math/clc_sqrt_cr.cl
+)
diff --git a/libclc/clc/lib/ptx-nvidiacl/CMakeLists.txt 
b/libclc/clc/lib/nvptx/CMakeLists.txt
similarity index 83%
rename from libclc/clc/lib/ptx-nvidiacl/CMakeLists.txt
rename to libclc/clc/lib/nvptx/CMakeLists.txt
index 6eb0baab1c0bb..a6e8544f17a1d 100644
--- a/libclc/clc/lib/ptx-nvidiacl/CMakeLists.txt
+++ b/libclc/clc/lib/nvptx/CMakeLists.txt
@@ -1,5 +1,4 @@
-libclc_configure_source_list(CLC_PTX_NVIDIACL_SOURCES
-  ${CMAKE_CURRENT_SOURCE_DIR}
+libclc_add_sources(${LIBCLC_CLC_TARGET}
   math/clc_log.cl
   math/clc_rsqrt.cl
   math/clc_sinpi.cl
diff --git a/libclc/clc/lib/ptx-nvidiacl/math/clc_log.cl 
b/libclc/clc/lib/nvptx/math/clc_log.cl
similarity index 100%
rename from libclc/clc/lib/ptx-nvidiacl/math/clc_log.cl
rename to libclc/clc/lib/nvptx/math/clc_log.cl
diff --git a/libclc/clc/lib/ptx-nvidiacl/math/clc_rsqrt.cl 
b/libclc/clc/lib/nvptx/math/clc_rsqrt.cl
similarity index 100%
rename from libclc/clc/lib/ptx-nvidiacl/math/clc_rsqrt.cl
rename to libclc/clc/lib/nvptx/math/clc_rsqrt.cl
diff --git a/libclc/clc/lib/ptx-nvidiacl/math/clc_sinpi.cl 
b/libclc/clc/lib/nvptx/math/clc_sinpi.cl
similarity index 100%
rename from libclc/clc/lib/ptx-nvidiacl/math/clc_sinpi.cl
rename to libclc/clc/lib/nvptx/math/clc_sinpi.cl
diff --git a/libclc/clc/lib/ptx-nvidiacl/math/clc_sqrt.cl 
b/libclc/clc/lib/nvptx/math/clc_sqrt.cl
similarity index 100%
rename from libclc/clc/lib/ptx-nvidiacl/math/clc_sqrt.cl
rename to libclc/clc/lib/nvptx/math/clc_sqrt.cl
diff --git a/libclc/clc/lib/ptx-nvidiacl/relational/clc_isinf.cl 
b/libclc/clc/lib/nvptx/relational/clc_isinf.cl
similarity index 100%
rename from libclc/clc/lib/ptx-nvidiacl/relational/clc_isinf.cl
rename to libclc/clc/lib/nvptx/relational/clc_isinf.cl
diff --git 
a/libclc/clc/lib/ptx-nvidiacl/synchronization/clc_work_group_barrier.cl 
b/libclc/clc/lib/nvptx/synchronization/clc_work_group_barrier.cl
similarity index 100%
rename from 
libclc/clc/lib/ptx-nvidiacl/synchronization/clc_work_group_barrier.cl
rename to libclc/clc/lib/nvptx/synchronization/clc_work_group_barrier.cl
diff --git a/libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_global_id.cl 
b/libclc/clc/lib/nvptx/workitem/clc_get_global_id.cl
similarity index 100%
rename from libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_global_id.cl
rename to libclc/clc/lib/nvptx/workitem/clc_get_global_id.cl
diff --git a/libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_global_size.cl 
b/libclc/clc/lib/nvptx/workitem/clc_get_global_size.cl
similarity index 100%
rename from libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_global_size.cl
rename to libclc/clc/lib/nvptx/workitem/clc_get_global_size.cl
diff --git a/libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_group_id.cl 
b/libclc/clc/lib/nvptx/workitem/clc_get_group_id.cl
similarity index 100%
rename from libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_group_id.cl
rename to libclc/clc/lib/nvptx/workitem/clc_get_group_id.cl
diff --git a/libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_local_id.cl 
b/libclc/clc/lib/nvptx/workitem/clc_get_local_id.cl
similarity index 100%
rename from libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_local_id.cl
rename to libclc/clc/lib/nvptx/workitem/clc_get_local_id.cl
diff --git a/libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_local_size.cl 
b/libclc/clc/lib/nvptx/workitem/clc_get_local_size.cl
similarity index 100%
rename from libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_local_size.cl
rename to libclc/clc/lib/nvptx/workitem/clc_get_local_size.cl
diff --git a/libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_max_sub_group_size.cl 
b/libclc/clc/lib/nvptx/workitem/clc_get_max_sub_group_size.cl
similarity index 100%
rename from libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_max_sub_group_size.cl
rename to libclc/clc/lib/nvptx/workitem/clc_get_max_sub_group_size.cl
diff --git a/libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_num_groups.cl 
b/libclc/clc/lib/nvptx/workitem/clc_get_num_groups.cl
similarity index 100%
rename from libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_num_groups.cl
rename to libclc/clc/lib/nvptx/workitem/clc_get_num_groups.cl
diff --git a/libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_sub_group_local_id.cl 
b/libclc/clc/lib/nvptx/workitem/clc_get_sub_group_local_id.cl
similarity index 100%
rename from libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_sub_group_local_id.cl
rename to libclc/clc/lib/nvptx/workitem/clc_get_sub_group_local_id.cl
diff --git a/libclc/clc/lib/spirv/CMakeLists.txt 
b/libclc/clc/lib/spirv/CMakeLists.txt
index b7481615b9414..6997a64731530 100644
--- a/libclc/clc/lib/spirv/CMakeLists.txt
+++ b/libclc/clc/lib/spirv/CMakeLists.txt
@@ -1,5 +1,8 @@
-libclc_configure_source_list(CLC_SPIRV_SOURCES
-  ${CMAKE_CURRENT_SOURCE_DIR}
+if(LIBCLC_TARGET_OS AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBCLC_TARGET_OS})
+  add_subdirectory(${LIBCLC_TARGET_OS})
+endif()
+
+libclc_add_sources(${LIBCLC_CLC_TARGET}
   math/clc_fmax.cl
   math/clc_fmin.cl
   subnormal_config.cl
diff --git a/libclc/clc/lib/spirv/vulkan/CMakeLists.txt 
b/libclc/clc/lib/spirv/vulkan/CMakeLists.txt
new file mode 100644
index 0000000000000..9bfd2e20c2869
--- /dev/null
+++ b/libclc/clc/lib/spirv/vulkan/CMakeLists.txt
@@ -0,0 +1,4 @@
+libclc_add_sources(${LIBCLC_CLC_TARGET}
+  integer/clc_mul_hi.cl
+  math/clc_sw_fma.cl
+)
diff --git a/libclc/clc/lib/vulkan/integer/clc_mul_hi.cl 
b/libclc/clc/lib/spirv/vulkan/integer/clc_mul_hi.cl
similarity index 100%
rename from libclc/clc/lib/vulkan/integer/clc_mul_hi.cl
rename to libclc/clc/lib/spirv/vulkan/integer/clc_mul_hi.cl
diff --git a/libclc/clc/lib/vulkan/math/clc_sw_fma.cl 
b/libclc/clc/lib/spirv/vulkan/math/clc_sw_fma.cl
similarity index 100%
rename from libclc/clc/lib/vulkan/math/clc_sw_fma.cl
rename to libclc/clc/lib/spirv/vulkan/math/clc_sw_fma.cl
diff --git a/libclc/clc/lib/vulkan/CMakeLists.txt 
b/libclc/clc/lib/vulkan/CMakeLists.txt
deleted file mode 100644
index 172e3be32d65c..0000000000000
--- a/libclc/clc/lib/vulkan/CMakeLists.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-libclc_configure_source_list(CLC_VULKAN_SOURCES
-  ${CMAKE_CURRENT_SOURCE_DIR}
-  integer/clc_mul_hi.cl
-  math/clc_sw_fma.cl
-)
diff --git a/libclc/cmake/modules/AddLibclc.cmake 
b/libclc/cmake/modules/AddLibclc.cmake
index 41297e8eb1e92..8833ad9b8a732 100644
--- a/libclc/cmake/modules/AddLibclc.cmake
+++ b/libclc/cmake/modules/AddLibclc.cmake
@@ -1,67 +1,68 @@
-# Converts a list of relative source paths to absolute paths and exports
-# it to the parent scope.
-macro(libclc_configure_source_list variable path)
-  set(${variable} ${ARGN})
-  list(TRANSFORM ${variable} PREPEND "${path}/")
-  set(${variable} ${${variable}} PARENT_SCOPE)
-endmacro()
-
-# Appends a compile option to the given source files. Paths are relative
-# to `path` and the property is set in the top-level libclc directory scope.
-macro(libclc_configure_source_options path option)
-  set(_option_srcs ${ARGN})
-  list(TRANSFORM _option_srcs PREPEND "${path}/")
-  set_property(SOURCE ${_option_srcs}
-    DIRECTORY ${LIBCLC_SOURCE_DIR}
-    APPEND PROPERTY COMPILE_OPTIONS ${option}
-  )
-endmacro()
-
-# Merges OpenCL C source file lists with priority deduplication.
-#
-# All arguments after the output variable name are treated as source file
-# paths. When multiple files share the same basename, the last occurrence
-# wins. This allows target-specific files to automatically override generic
-# ones.
-function(libclc_merge_sources output)
-  set(all_sources ${ARGN})
-  set(result)
-  set(seen_names)
-
-  list(REVERSE all_sources)
-  foreach(f ${all_sources})
-    get_filename_component(name "${f}" NAME)
-    if(NOT name IN_LIST seen_names)
-      list(APPEND seen_names "${name}")
-      list(PREPEND result "${f}")
+# Adds source files to a libclc builtin library target with deduplication. If a
+# source with the same basename already exists in the target's SOURCES 
property,
+# the new file is skipped.
+function(libclc_add_sources target)
+  cmake_parse_arguments(ARG "" "BASE_DIR" "" ${ARGN})
+  if(NOT ARG_BASE_DIR)
+    set(ARG_BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+  endif()
+
+  get_target_property(existing ${target} SOURCES)
+  if(NOT existing)
+    set(existing "")
+  endif()
+
+  set(seen)
+  foreach(file ${existing})
+    get_filename_component(name "${file}" NAME)
+    list(APPEND seen "${name}")
+  endforeach()
+
+  set(new_sources)
+  foreach(rel_src ${ARG_UNPARSED_ARGUMENTS})
+    get_filename_component(name "${rel_src}" NAME)
+    if(NOT name IN_LIST seen)
+      list(APPEND new_sources "${ARG_BASE_DIR}/${rel_src}")
+      list(APPEND seen "${name}")
     endif()
   endforeach()
 
-  set(${output} ${result} PARENT_SCOPE)
+  if(new_sources)
+    target_sources(${target} PRIVATE ${new_sources})
+    set(inc_dirs)
+    foreach(file ${new_sources})
+      get_filename_component(dir "${file}" DIRECTORY)
+      list(APPEND inc_dirs "${dir}")
+    endforeach()
+    list(REMOVE_DUPLICATES inc_dirs)
+    target_include_directories(${target} PRIVATE ${inc_dirs})
+  endif()
 endfunction()
 
-# Creates a static library target for libclc builtins. Derives include
-# directories to locate `.inc` files in the same directory.
-function(add_libclc_builtin_library target_name)
+# Appends a compile option to the given source files. Source paths are
+# relative to CMAKE_CURRENT_SOURCE_DIR. The property is set in the
+# top-level libclc directory scope.
+function(libclc_set_source_options option)
+  set(srcs ${ARGN})
+  list(TRANSFORM srcs PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/")
+  set_property(SOURCE ${srcs}
+    DIRECTORY ${LIBCLC_SOURCE_DIR}
+    APPEND PROPERTY COMPILE_OPTIONS ${option}
+  )
+endfunction()
+
+# Configures compile options, include directories, definitions, and
+# properties on an existing libclc builtin library target.
+function(libclc_configure_library target_name)
   cmake_parse_arguments(ARG
     ""
     "FOLDER"
-    "SOURCES;COMPILE_OPTIONS;INCLUDE_DIRS;COMPILE_DEFINITIONS"
+    "COMPILE_OPTIONS;INCLUDE_DIRS;COMPILE_DEFINITIONS"
     ${ARGN}
   )
 
-  set(_inc_dirs)
-  foreach(f ${ARG_SOURCES})
-    get_filename_component(dir ${f} DIRECTORY)
-    list(APPEND _inc_dirs ${dir})
-  endforeach()
-  list(REMOVE_DUPLICATES _inc_dirs)
-
-  add_library(${target_name} STATIC ${ARG_SOURCES})
   target_compile_options(${target_name} PRIVATE ${ARG_COMPILE_OPTIONS})
-  target_include_directories(${target_name} PRIVATE
-    ${ARG_INCLUDE_DIRS} ${_inc_dirs}
-  )
+  target_include_directories(${target_name} PRIVATE ${ARG_INCLUDE_DIRS})
   target_compile_definitions(${target_name} PRIVATE ${ARG_COMPILE_DEFINITIONS})
   set_target_properties(${target_name} PROPERTIES
     ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
@@ -71,7 +72,7 @@ endfunction()
 
 # Links one or more libclc builtin libraries together, optionally
 # internalizing dependencies, then produces a final .bc or .spv file.
-function(link_libclc_builtin_library target_name)
+function(libclc_link_library target_name)
   cmake_parse_arguments(ARG
     ""
     "ARCH;TRIPLE;TARGET_TRIPLE;FOLDER;OUTPUT_FILENAME"
@@ -80,10 +81,10 @@ function(link_libclc_builtin_library target_name)
   )
 
   if(NOT ARG_OUTPUT_FILENAME)
-    message(FATAL_ERROR "OUTPUT_FILENAME is required for 
link_libclc_builtin_library")
+    message(FATAL_ERROR "OUTPUT_FILENAME is required for libclc_link_library")
   endif()
   if(NOT ARG_LIBRARIES)
-    message(FATAL_ERROR "LIBRARIES is required for 
link_libclc_builtin_library")
+    message(FATAL_ERROR "LIBRARIES is required for libclc_link_library")
   endif()
 
   set(library_dir ${LIBCLC_OUTPUT_LIBRARY_DIR}/${ARG_TARGET_TRIPLE})
@@ -113,7 +114,7 @@ function(link_libclc_builtin_library target_name)
 
   string(REPLACE "-" ";" triple_parts "${ARG_TRIPLE}")
   list(GET triple_parts 2 triple_os)
-  if((ARG_ARCH STREQUAL spirv OR ARG_ARCH STREQUAL spirv32 OR ARG_ARCH 
STREQUAL spirv64) AND NOT triple_os STREQUAL vulkan)
+  if(ARG_ARCH IN_LIST LIBCLC_ARCHS_SPIRV AND NOT triple_os STREQUAL vulkan)
     # SPIR-V targets produce a .spv file from the linked bitcode.
     set(builtins_lib ${library_dir}/${ARG_OUTPUT_FILENAME}.spv)
     if(LIBCLC_USE_SPIRV_BACKEND)
@@ -148,41 +149,31 @@ function(link_libclc_builtin_library target_name)
   )
 endfunction()
 
-# Builds a builtins library from sources, links it with any internalized
-# dependencies via link_libclc_builtin_library, and adds a verification test
-# for unresolved symbols.
-function(add_libclc_library target_name)
+# Links builtin library targets, produces the final output file, and
+# registers it for installation.
+function(libclc_add_library target_name)
   cmake_parse_arguments(ARG
     ""
     "ARCH;TRIPLE;TARGET_TRIPLE;OUTPUT_FILENAME;PARENT_TARGET"
-    
"SOURCES;COMPILE_OPTIONS;INCLUDE_DIRS;COMPILE_DEFINITIONS;INTERNALIZE_LIBRARIES;OPT_FLAGS"
+    "LIBRARIES;INTERNALIZE_LIBRARIES;OPT_FLAGS"
     ${ARGN}
   )
 
   if(NOT ARG_OUTPUT_FILENAME)
-    message(FATAL_ERROR "OUTPUT_FILENAME is required for add_libclc_library")
+    message(FATAL_ERROR "OUTPUT_FILENAME is required for libclc_add_library")
   endif()
   if(NOT ARG_PARENT_TARGET)
-    message(FATAL_ERROR "PARENT_TARGET is required for add_libclc_library")
+    message(FATAL_ERROR "PARENT_TARGET is required for libclc_add_library")
   endif()
-  if(NOT ARG_SOURCES)
-    message(FATAL_ERROR "SOURCES is required for add_libclc_library")
+  if(NOT ARG_LIBRARIES)
+    message(FATAL_ERROR "LIBRARIES is required for libclc_add_library")
   endif()
 
-  set(builtins_target ${target_name}_clc_builtins)
-  add_libclc_builtin_library(${builtins_target}
-    SOURCES ${ARG_SOURCES}
-    COMPILE_OPTIONS ${ARG_COMPILE_OPTIONS}
-    INCLUDE_DIRS ${ARG_INCLUDE_DIRS}
-    COMPILE_DEFINITIONS ${ARG_COMPILE_DEFINITIONS}
-    FOLDER "libclc/Device IR/Intermediate"
-  )
-
-  link_libclc_builtin_library(${target_name}
+  libclc_link_library(${target_name}
     ARCH ${ARG_ARCH}
     TRIPLE ${ARG_TRIPLE}
     TARGET_TRIPLE ${ARG_TARGET_TRIPLE}
-    LIBRARIES ${builtins_target}
+    LIBRARIES ${ARG_LIBRARIES}
     INTERNALIZE_LIBRARIES ${ARG_INTERNALIZE_LIBRARIES}
     OPT_FLAGS ${ARG_OPT_FLAGS}
     OUTPUT_FILENAME "${ARG_OUTPUT_FILENAME}"
diff --git a/libclc/opencl/CMakeLists.txt b/libclc/opencl/CMakeLists.txt
new file mode 100644
index 0000000000000..b92eb5fb95484
--- /dev/null
+++ b/libclc/opencl/CMakeLists.txt
@@ -0,0 +1,6 @@
+if(LIBCLC_ARCH_DIR AND EXISTS 
${CMAKE_CURRENT_SOURCE_DIR}/lib/${LIBCLC_ARCH_DIR})
+  add_subdirectory(lib/${LIBCLC_ARCH_DIR})
+endif()
+if(NOT LIBCLC_TARGET_ARCH IN_LIST LIBCLC_ARCHS_SPIRV)
+  add_subdirectory(lib/generic)
+endif()
diff --git a/libclc/opencl/lib/amdgpu/CMakeLists.txt 
b/libclc/opencl/lib/amdgpu/CMakeLists.txt
index a42f2751906bf..c6d2c6850eb66 100644
--- a/libclc/opencl/lib/amdgpu/CMakeLists.txt
+++ b/libclc/opencl/lib/amdgpu/CMakeLists.txt
@@ -1,5 +1,4 @@
-libclc_configure_source_list(OPENCL_AMDGCN_SOURCES
-  ${CMAKE_CURRENT_SOURCE_DIR}
+libclc_add_sources(${LIBCLC_OPENCL_TARGET}
   async/wait_group_events.cl
   printf/__printf_alloc.cl
 )
diff --git a/libclc/opencl/lib/generic/CMakeLists.txt 
b/libclc/opencl/lib/generic/CMakeLists.txt
index 4ad60248139ae..a4b0a9769d688 100644
--- a/libclc/opencl/lib/generic/CMakeLists.txt
+++ b/libclc/opencl/lib/generic/CMakeLists.txt
@@ -1,5 +1,4 @@
-libclc_configure_source_list(OPENCL_GENERIC_SOURCES
-  ${CMAKE_CURRENT_SOURCE_DIR}
+libclc_add_sources(${LIBCLC_OPENCL_TARGET}
   address_space/qualifier.cl
   async/async_work_group_copy.cl
   async/async_work_group_strided_copy.cl
@@ -227,7 +226,7 @@ libclc_configure_source_list(OPENCL_GENERIC_SOURCES
   workitem/get_work_dim.cl
 )
 
-libclc_configure_source_options(${CMAKE_CURRENT_SOURCE_DIR} -fapprox-func
+libclc_set_source_options(-fapprox-func
   math/native_cos.cl
   math/native_divide.cl
   math/native_exp.cl
diff --git a/libclc/opencl/lib/spirv/CMakeLists.txt 
b/libclc/opencl/lib/spirv/CMakeLists.txt
index ab6fea0692c09..4db531cc3c6bc 100644
--- a/libclc/opencl/lib/spirv/CMakeLists.txt
+++ b/libclc/opencl/lib/spirv/CMakeLists.txt
@@ -1,9 +1,11 @@
-set(_gen ${CMAKE_CURRENT_SOURCE_DIR}/../generic)
+if(LIBCLC_TARGET_OS AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBCLC_TARGET_OS})
+  add_subdirectory(${LIBCLC_TARGET_OS})
+  return()
+endif()
 
-# SPIR-V uses a curated subset of generic builtins, so this list is
-# self-contained rather than merged with the generic set.
-libclc_configure_source_list(OPENCL_SPIRV_SOURCES
-  ${_gen}
+# Non-Vulkan SPIR-V uses a curated subset of generic builtins.
+libclc_add_sources(${LIBCLC_OPENCL_TARGET}
+  BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../generic
   async/async_work_group_strided_copy.cl
   async/wait_group_events.cl
   common/degrees.cl
diff --git a/libclc/opencl/lib/vulkan/CMakeLists.txt 
b/libclc/opencl/lib/spirv/vulkan/CMakeLists.txt
similarity index 85%
rename from libclc/opencl/lib/vulkan/CMakeLists.txt
rename to libclc/opencl/lib/spirv/vulkan/CMakeLists.txt
index 5fa2e7a367678..158f0e6d038d9 100644
--- a/libclc/opencl/lib/vulkan/CMakeLists.txt
+++ b/libclc/opencl/lib/spirv/vulkan/CMakeLists.txt
@@ -1,9 +1,6 @@
-set(_gen ${CMAKE_CURRENT_SOURCE_DIR}/../generic)
-
 # Vulkan uses a curated subset of generic builtins plus its own overrides,
 # so this list is self-contained rather than merged with the generic set.
-libclc_configure_source_list(_vulkan_sources
-  ${CMAKE_CURRENT_SOURCE_DIR}
+libclc_add_sources(${LIBCLC_OPENCL_TARGET}
   conversion/convert_float2float.cl
   conversion/convert_float2int.cl
   conversion/convert_int2float.cl
@@ -12,8 +9,8 @@ libclc_configure_source_list(_vulkan_sources
   shared/vstore_half.cl
 )
 
-libclc_configure_source_list(_gen_sources
-  ${_gen}
+libclc_add_sources(${LIBCLC_OPENCL_TARGET}
+  BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../generic
   geometric/distance.cl
   geometric/length.cl
   math/acos.cl
@@ -84,5 +81,3 @@ libclc_configure_source_list(_gen_sources
   math/tanpi.cl
   math/tgamma.cl
 )
-
-set(OPENCL_VULKAN_SOURCES ${_vulkan_sources} ${_gen_sources} PARENT_SCOPE)
diff --git a/libclc/opencl/lib/vulkan/conversion/convert_float.inc 
b/libclc/opencl/lib/spirv/vulkan/conversion/convert_float.inc
similarity index 100%
rename from libclc/opencl/lib/vulkan/conversion/convert_float.inc
rename to libclc/opencl/lib/spirv/vulkan/conversion/convert_float.inc
diff --git a/libclc/opencl/lib/vulkan/conversion/convert_float2float.cl 
b/libclc/opencl/lib/spirv/vulkan/conversion/convert_float2float.cl
similarity index 100%
rename from libclc/opencl/lib/vulkan/conversion/convert_float2float.cl
rename to libclc/opencl/lib/spirv/vulkan/conversion/convert_float2float.cl
diff --git a/libclc/opencl/lib/vulkan/conversion/convert_float2int.cl 
b/libclc/opencl/lib/spirv/vulkan/conversion/convert_float2int.cl
similarity index 100%
rename from libclc/opencl/lib/vulkan/conversion/convert_float2int.cl
rename to libclc/opencl/lib/spirv/vulkan/conversion/convert_float2int.cl
diff --git a/libclc/opencl/lib/vulkan/conversion/convert_int2float.cl 
b/libclc/opencl/lib/spirv/vulkan/conversion/convert_int2float.cl
similarity index 100%
rename from libclc/opencl/lib/vulkan/conversion/convert_int2float.cl
rename to libclc/opencl/lib/spirv/vulkan/conversion/convert_int2float.cl
diff --git a/libclc/opencl/lib/vulkan/conversion/convert_integer.cl 
b/libclc/opencl/lib/spirv/vulkan/conversion/convert_integer.cl
similarity index 100%
rename from libclc/opencl/lib/vulkan/conversion/convert_integer.cl
rename to libclc/opencl/lib/spirv/vulkan/conversion/convert_integer.cl
diff --git a/libclc/opencl/lib/vulkan/conversion/convert_integer.inc 
b/libclc/opencl/lib/spirv/vulkan/conversion/convert_integer.inc
similarity index 100%
rename from libclc/opencl/lib/vulkan/conversion/convert_integer.inc
rename to libclc/opencl/lib/spirv/vulkan/conversion/convert_integer.inc
diff --git a/libclc/opencl/lib/vulkan/math/fma.cl 
b/libclc/opencl/lib/spirv/vulkan/math/fma.cl
similarity index 100%
rename from libclc/opencl/lib/vulkan/math/fma.cl
rename to libclc/opencl/lib/spirv/vulkan/math/fma.cl
diff --git a/libclc/opencl/lib/vulkan/shared/vstore_half.cl 
b/libclc/opencl/lib/spirv/vulkan/shared/vstore_half.cl
similarity index 100%
rename from libclc/opencl/lib/vulkan/shared/vstore_half.cl
rename to libclc/opencl/lib/spirv/vulkan/shared/vstore_half.cl
diff --git a/libclc/opencl/lib/vulkan/shared/vstore_half.inc 
b/libclc/opencl/lib/spirv/vulkan/shared/vstore_half.inc
similarity index 100%
rename from libclc/opencl/lib/vulkan/shared/vstore_half.inc
rename to libclc/opencl/lib/spirv/vulkan/shared/vstore_half.inc

>From 77abdf9684e15a2cceb402758319e10fc4e6bffd Mon Sep 17 00:00:00 2001
From: Joseph Huber <[email protected]>
Date: Mon, 11 May 2026 20:29:03 -0500
Subject: [PATCH 2/4] Comments

---
 libclc/clc/CMakeLists.txt                     |  1 +
 libclc/clc/lib/amdgpu/CMakeLists.txt          |  2 +-
 libclc/clc/lib/generic/CMakeLists.txt         |  2 +-
 libclc/clc/lib/nvptx/CMakeLists.txt           |  2 +-
 libclc/clc/lib/spirv/CMakeLists.txt           |  2 +-
 libclc/clc/lib/spirv/vulkan/CMakeLists.txt    |  2 +-
 libclc/cmake/modules/AddLibclc.cmake          | 19 ++++++++++---------
 libclc/opencl/CMakeLists.txt                  |  3 +++
 libclc/opencl/lib/amdgpu/CMakeLists.txt       |  2 +-
 libclc/opencl/lib/generic/CMakeLists.txt      |  2 +-
 libclc/opencl/lib/spirv/CMakeLists.txt        |  1 +
 libclc/opencl/lib/spirv/vulkan/CMakeLists.txt |  3 ++-
 12 files changed, 24 insertions(+), 17 deletions(-)

diff --git a/libclc/clc/CMakeLists.txt b/libclc/clc/CMakeLists.txt
index bcec1bf9406ab..bd75adcf75243 100644
--- a/libclc/clc/CMakeLists.txt
+++ b/libclc/clc/CMakeLists.txt
@@ -1,3 +1,4 @@
+# Add the target specific files first so they can override the generic 
fallback.
 if(LIBCLC_ARCH_DIR AND EXISTS 
${CMAKE_CURRENT_SOURCE_DIR}/lib/${LIBCLC_ARCH_DIR})
   add_subdirectory(lib/${LIBCLC_ARCH_DIR})
 endif()
diff --git a/libclc/clc/lib/amdgpu/CMakeLists.txt 
b/libclc/clc/lib/amdgpu/CMakeLists.txt
index cdeadbd3b9373..910a0cf1765df 100644
--- a/libclc/clc/lib/amdgpu/CMakeLists.txt
+++ b/libclc/clc/lib/amdgpu/CMakeLists.txt
@@ -1,4 +1,4 @@
-libclc_add_sources(${LIBCLC_CLC_TARGET}
+libclc_add_sources(${LIBCLC_CLC_TARGET} FILES
   address_space/clc_qualifier.cl
   math/clc_cbrt.cl
   math/clc_exp.cl
diff --git a/libclc/clc/lib/generic/CMakeLists.txt 
b/libclc/clc/lib/generic/CMakeLists.txt
index 8124e9471ffb7..40261545fce91 100644
--- a/libclc/clc/lib/generic/CMakeLists.txt
+++ b/libclc/clc/lib/generic/CMakeLists.txt
@@ -1,4 +1,4 @@
-libclc_add_sources(${LIBCLC_CLC_TARGET}
+libclc_add_sources(${LIBCLC_CLC_TARGET} FILES
   async/clc_prefetch.cl
   atomic/clc_atomic_compare_exchange.cl
   atomic/clc_atomic_dec.cl
diff --git a/libclc/clc/lib/nvptx/CMakeLists.txt 
b/libclc/clc/lib/nvptx/CMakeLists.txt
index a6e8544f17a1d..2345d5aeed77b 100644
--- a/libclc/clc/lib/nvptx/CMakeLists.txt
+++ b/libclc/clc/lib/nvptx/CMakeLists.txt
@@ -1,4 +1,4 @@
-libclc_add_sources(${LIBCLC_CLC_TARGET}
+libclc_add_sources(${LIBCLC_CLC_TARGET} FILES
   math/clc_log.cl
   math/clc_rsqrt.cl
   math/clc_sinpi.cl
diff --git a/libclc/clc/lib/spirv/CMakeLists.txt 
b/libclc/clc/lib/spirv/CMakeLists.txt
index 6997a64731530..5f361c95c4003 100644
--- a/libclc/clc/lib/spirv/CMakeLists.txt
+++ b/libclc/clc/lib/spirv/CMakeLists.txt
@@ -2,7 +2,7 @@ if(LIBCLC_TARGET_OS AND EXISTS 
${CMAKE_CURRENT_SOURCE_DIR}/${LIBCLC_TARGET_OS})
   add_subdirectory(${LIBCLC_TARGET_OS})
 endif()
 
-libclc_add_sources(${LIBCLC_CLC_TARGET}
+libclc_add_sources(${LIBCLC_CLC_TARGET} FILES
   math/clc_fmax.cl
   math/clc_fmin.cl
   subnormal_config.cl
diff --git a/libclc/clc/lib/spirv/vulkan/CMakeLists.txt 
b/libclc/clc/lib/spirv/vulkan/CMakeLists.txt
index 9bfd2e20c2869..499ce274a500c 100644
--- a/libclc/clc/lib/spirv/vulkan/CMakeLists.txt
+++ b/libclc/clc/lib/spirv/vulkan/CMakeLists.txt
@@ -1,4 +1,4 @@
-libclc_add_sources(${LIBCLC_CLC_TARGET}
+libclc_add_sources(${LIBCLC_CLC_TARGET} FILES
   integer/clc_mul_hi.cl
   math/clc_sw_fma.cl
 )
diff --git a/libclc/cmake/modules/AddLibclc.cmake 
b/libclc/cmake/modules/AddLibclc.cmake
index 8833ad9b8a732..2b1b3a9b8e86d 100644
--- a/libclc/cmake/modules/AddLibclc.cmake
+++ b/libclc/cmake/modules/AddLibclc.cmake
@@ -1,25 +1,26 @@
 # Adds source files to a libclc builtin library target with deduplication. If a
-# source with the same basename already exists in the target's SOURCES 
property,
-# the new file is skipped.
+# source with the same basename already exists in the target's SOURCES property
+# the new file is skipped. This enables target-specific directories to override
+# generic implementations when they are included first.
+#
+# Sources are specified as paths relative to CMAKE_CURRENT_SOURCE_DIR, or
+# relative to BASE_DIR if provided.
 function(libclc_add_sources target)
-  cmake_parse_arguments(ARG "" "BASE_DIR" "" ${ARGN})
+  cmake_parse_arguments(ARG "" "BASE_DIR" "FILES" ${ARGN})
   if(NOT ARG_BASE_DIR)
     set(ARG_BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
   endif()
 
   get_target_property(existing ${target} SOURCES)
-  if(NOT existing)
-    set(existing "")
-  endif()
 
   set(seen)
-  foreach(file ${existing})
+  foreach(file IN LISTS existing)
     get_filename_component(name "${file}" NAME)
     list(APPEND seen "${name}")
   endforeach()
 
   set(new_sources)
-  foreach(rel_src ${ARG_UNPARSED_ARGUMENTS})
+  foreach(rel_src IN LISTS ARG_FILES)
     get_filename_component(name "${rel_src}" NAME)
     if(NOT name IN_LIST seen)
       list(APPEND new_sources "${ARG_BASE_DIR}/${rel_src}")
@@ -30,7 +31,7 @@ function(libclc_add_sources target)
   if(new_sources)
     target_sources(${target} PRIVATE ${new_sources})
     set(inc_dirs)
-    foreach(file ${new_sources})
+    foreach(file IN LISTS new_sources)
       get_filename_component(dir "${file}" DIRECTORY)
       list(APPEND inc_dirs "${dir}")
     endforeach()
diff --git a/libclc/opencl/CMakeLists.txt b/libclc/opencl/CMakeLists.txt
index b92eb5fb95484..8b4ac40ea827a 100644
--- a/libclc/opencl/CMakeLists.txt
+++ b/libclc/opencl/CMakeLists.txt
@@ -1,6 +1,9 @@
+# Add the target specific files first so they can override the generic 
fallback.
 if(LIBCLC_ARCH_DIR AND EXISTS 
${CMAKE_CURRENT_SOURCE_DIR}/lib/${LIBCLC_ARCH_DIR})
   add_subdirectory(lib/${LIBCLC_ARCH_DIR})
 endif()
+
+# SPIR-V targets cannot use the generic list of generic functions yet.
 if(NOT LIBCLC_TARGET_ARCH IN_LIST LIBCLC_ARCHS_SPIRV)
   add_subdirectory(lib/generic)
 endif()
diff --git a/libclc/opencl/lib/amdgpu/CMakeLists.txt 
b/libclc/opencl/lib/amdgpu/CMakeLists.txt
index c6d2c6850eb66..16a75349d8a4a 100644
--- a/libclc/opencl/lib/amdgpu/CMakeLists.txt
+++ b/libclc/opencl/lib/amdgpu/CMakeLists.txt
@@ -1,4 +1,4 @@
-libclc_add_sources(${LIBCLC_OPENCL_TARGET}
+libclc_add_sources(${LIBCLC_OPENCL_TARGET} FILES
   async/wait_group_events.cl
   printf/__printf_alloc.cl
 )
diff --git a/libclc/opencl/lib/generic/CMakeLists.txt 
b/libclc/opencl/lib/generic/CMakeLists.txt
index a4b0a9769d688..5768ba9446ff1 100644
--- a/libclc/opencl/lib/generic/CMakeLists.txt
+++ b/libclc/opencl/lib/generic/CMakeLists.txt
@@ -1,4 +1,4 @@
-libclc_add_sources(${LIBCLC_OPENCL_TARGET}
+libclc_add_sources(${LIBCLC_OPENCL_TARGET} FILES
   address_space/qualifier.cl
   async/async_work_group_copy.cl
   async/async_work_group_strided_copy.cl
diff --git a/libclc/opencl/lib/spirv/CMakeLists.txt 
b/libclc/opencl/lib/spirv/CMakeLists.txt
index 4db531cc3c6bc..ea35940f60d70 100644
--- a/libclc/opencl/lib/spirv/CMakeLists.txt
+++ b/libclc/opencl/lib/spirv/CMakeLists.txt
@@ -6,6 +6,7 @@ endif()
 # Non-Vulkan SPIR-V uses a curated subset of generic builtins.
 libclc_add_sources(${LIBCLC_OPENCL_TARGET}
   BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../generic
+  FILES
   async/async_work_group_strided_copy.cl
   async/wait_group_events.cl
   common/degrees.cl
diff --git a/libclc/opencl/lib/spirv/vulkan/CMakeLists.txt 
b/libclc/opencl/lib/spirv/vulkan/CMakeLists.txt
index 158f0e6d038d9..d04959027f0de 100644
--- a/libclc/opencl/lib/spirv/vulkan/CMakeLists.txt
+++ b/libclc/opencl/lib/spirv/vulkan/CMakeLists.txt
@@ -1,6 +1,6 @@
 # Vulkan uses a curated subset of generic builtins plus its own overrides,
 # so this list is self-contained rather than merged with the generic set.
-libclc_add_sources(${LIBCLC_OPENCL_TARGET}
+libclc_add_sources(${LIBCLC_OPENCL_TARGET} FILES
   conversion/convert_float2float.cl
   conversion/convert_float2int.cl
   conversion/convert_int2float.cl
@@ -11,6 +11,7 @@ libclc_add_sources(${LIBCLC_OPENCL_TARGET}
 
 libclc_add_sources(${LIBCLC_OPENCL_TARGET}
   BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../generic
+  FILES
   geometric/distance.cl
   geometric/length.cl
   math/acos.cl

>From f94f75b785eb9a91966dd115410773910b9065bb Mon Sep 17 00:00:00 2001
From: Joseph Huber <[email protected]>
Date: Mon, 11 May 2026 21:52:13 -0500
Subject: [PATCH 3/4] Factor into builtin library

---
 libclc/CMakeLists.txt                | 30 ++++++++++------------------
 libclc/cmake/modules/AddLibclc.cmake |  8 +++++---
 2 files changed, 16 insertions(+), 22 deletions(-)

diff --git a/libclc/CMakeLists.txt b/libclc/CMakeLists.txt
index 55f2d85dcdf51..6e292509b3650 100644
--- a/libclc/CMakeLists.txt
+++ b/libclc/CMakeLists.txt
@@ -122,22 +122,6 @@ foreach( tool IN ITEMS opt llvm-link )
   endif()
 endforeach()
 
-# Create library targets before add_subdirectory calls so that
-# subdirectories can add sources via libclc_add_sources().
-set(LIBCLC_CLC_TARGET clc)
-add_library(${LIBCLC_CLC_TARGET} STATIC)
-
-set(LIBCLC_OPENCL_TARGET opencl)
-add_library(${LIBCLC_OPENCL_TARGET} STATIC)
-
-add_subdirectory(clc)
-add_subdirectory(opencl)
-
-add_custom_target( libclc ALL )
-
-add_custom_target( libclc-opencl-builtins COMMENT "Build libclc OpenCL 
builtins" )
-add_dependencies( libclc libclc-opencl-builtins )
-
 # Determine the clang target triple. Vulkan and SPIR-V backend targets use the
 # triple directly; other SPIR-V targets fall back to the legacy SPIR target.
 set(clang_triple ${LIBCLC_TARGET})
@@ -203,15 +187,16 @@ set(common_defs
 )
 
 # Configure the CLC internal builtins library.
-libclc_configure_library(${LIBCLC_CLC_TARGET}
+set(LIBCLC_CLC_TARGET clc)
+libclc_add_builtin_library(${LIBCLC_CLC_TARGET}
   COMPILE_OPTIONS ${compile_flags}
   INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/clc/include
   COMPILE_DEFINITIONS ${common_defs}
   FOLDER "libclc/Device IR/CLC"
 )
 
-# Configure the OpenCL builtins library.
-libclc_configure_library(${LIBCLC_OPENCL_TARGET}
+set(LIBCLC_OPENCL_TARGET opencl)
+libclc_add_builtin_library(${LIBCLC_OPENCL_TARGET}
   COMPILE_OPTIONS ${compile_flags} "SHELL:-Xclang -fdeclare-opencl-builtins"
   INCLUDE_DIRS
     ${CMAKE_CURRENT_SOURCE_DIR}/clc/include
@@ -220,6 +205,13 @@ libclc_configure_library(${LIBCLC_OPENCL_TARGET}
   FOLDER "libclc/Device IR/Intermediate"
 )
 
+add_subdirectory(clc)
+add_subdirectory(opencl)
+
+add_custom_target(libclc ALL)
+add_custom_target(libclc-opencl-builtins COMMENT "Build libclc OpenCL 
builtins")
+add_dependencies(libclc libclc-opencl-builtins)
+
 # Link and install the final OpenCL builtins library.
 libclc_add_library(libclc-${LIBCLC_TARGET}
   ARCH ${LIBCLC_TARGET_ARCH}
diff --git a/libclc/cmake/modules/AddLibclc.cmake 
b/libclc/cmake/modules/AddLibclc.cmake
index 2b1b3a9b8e86d..2d547e13a4e04 100644
--- a/libclc/cmake/modules/AddLibclc.cmake
+++ b/libclc/cmake/modules/AddLibclc.cmake
@@ -52,9 +52,10 @@ function(libclc_set_source_options option)
   )
 endfunction()
 
-# Configures compile options, include directories, definitions, and
-# properties on an existing libclc builtin library target.
-function(libclc_configure_library target_name)
+# Creates a static library target for libclc builtins and configures its
+# compile options, include directories, and definitions. Subdirectories
+# populate sources via libclc_add_sources() after this call.
+function(libclc_add_builtin_library target_name)
   cmake_parse_arguments(ARG
     ""
     "FOLDER"
@@ -62,6 +63,7 @@ function(libclc_configure_library target_name)
     ${ARGN}
   )
 
+  add_library(${target_name} STATIC)
   target_compile_options(${target_name} PRIVATE ${ARG_COMPILE_OPTIONS})
   target_include_directories(${target_name} PRIVATE ${ARG_INCLUDE_DIRS})
   target_compile_definitions(${target_name} PRIVATE ${ARG_COMPILE_DEFINITIONS})

>From c258f845490b36de3a6b05b7bc44be5c6ccf88f6 Mon Sep 17 00:00:00 2001
From: Joseph Huber <[email protected]>
Date: Mon, 11 May 2026 22:14:10 -0500
Subject: [PATCH 4/4] put em back

---
 libclc/CMakeLists.txt | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/libclc/CMakeLists.txt b/libclc/CMakeLists.txt
index 6e292509b3650..334faa1a02667 100644
--- a/libclc/CMakeLists.txt
+++ b/libclc/CMakeLists.txt
@@ -186,6 +186,10 @@ set(common_defs
   __CLC_GENERIC_ADDRSPACE_VAL=${generic_addrspace_val}
 )
 
+add_custom_target(libclc ALL)
+add_custom_target(libclc-opencl-builtins COMMENT "Build libclc OpenCL 
builtins")
+add_dependencies(libclc libclc-opencl-builtins)
+
 # Configure the CLC internal builtins library.
 set(LIBCLC_CLC_TARGET clc)
 libclc_add_builtin_library(${LIBCLC_CLC_TARGET}
@@ -208,10 +212,6 @@ libclc_add_builtin_library(${LIBCLC_OPENCL_TARGET}
 add_subdirectory(clc)
 add_subdirectory(opencl)
 
-add_custom_target(libclc ALL)
-add_custom_target(libclc-opencl-builtins COMMENT "Build libclc OpenCL 
builtins")
-add_dependencies(libclc libclc-opencl-builtins)
-
 # Link and install the final OpenCL builtins library.
 libclc_add_library(libclc-${LIBCLC_TARGET}
   ARCH ${LIBCLC_TARGET_ARCH}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to