Skip to content

Ugly example of building libc to spirv #128585

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

JonChesterfield
Copy link
Collaborator

Hopefully we can do better before landing. Posting for discussion.

Didn't learn a huge amount. spirv rejects the clang::amdgpu_kernel annotation and I can't work out how that's supposed to be spelled.

Libc doesn't do anything with address spaces which upsets spirv (unlike openmp which does lots)

The libc build streams bitcode through lld which refuses to do anything with it, but that can be patched.

Port is mostly copying the amdgpu folders to spirv64. Not happy with cmake assuming that spirv64 means amdgpu but also don't understand how to stop it making that assumption.

Lots of libm seems to be dead. I'm hoping Joseph will delete said dead code as it makes this patch look excessively large.

Also doesn't seem ideal to have copy&pasted the config entrypoints stuff.

Don't have a loader, probably reasonable to write one that calls llvm to jit spirv though.

@llvmbot llvmbot added clang Clang issues not falling into any other category lld clang:frontend Language frontend issues, e.g. anything involving "Sema" libc lld:ELF offload labels Feb 24, 2025
@llvmbot
Copy link
Member

llvmbot commented Feb 24, 2025

@llvm/pr-subscribers-llvm-ir
@llvm/pr-subscribers-offload

@llvm/pr-subscribers-lld-elf

Author: Jon Chesterfield (JonChesterfield)

Changes

Hopefully we can do better before landing. Posting for discussion.

Didn't learn a huge amount. spirv rejects the clang::amdgpu_kernel annotation and I can't work out how that's supposed to be spelled.

Libc doesn't do anything with address spaces which upsets spirv (unlike openmp which does lots)

The libc build streams bitcode through lld which refuses to do anything with it, but that can be patched.

Port is mostly copying the amdgpu folders to spirv64. Not happy with cmake assuming that spirv64 means amdgpu but also don't understand how to stop it making that assumption.

Lots of libm seems to be dead. I'm hoping Joseph will delete said dead code as it makes this patch look excessively large.

Also doesn't seem ideal to have copy&pasted the config entrypoints stuff.

Don't have a loader, probably reasonable to write one that calls llvm to jit spirv though.


Patch is 136.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/128585.diff

119 Files Affected:

  • (modified) clang/lib/Basic/Targets/SPIR.h (+2)
  • (modified) libc/cmake/modules/LLVMLibCArchitectures.cmake (+4)
  • (added) libc/config/gpu/spirv64/config.json (+37)
  • (added) libc/config/gpu/spirv64/entrypoints.txt (+607)
  • (added) libc/config/gpu/spirv64/headers.txt (+21)
  • (added) libc/src/math/spirv64/CMakeLists.txt (+541)
  • (added) libc/src/math/spirv64/acos.cpp (+19)
  • (added) libc/src/math/spirv64/acosf.cpp (+19)
  • (added) libc/src/math/spirv64/acosh.cpp (+19)
  • (added) libc/src/math/spirv64/acoshf.cpp (+19)
  • (added) libc/src/math/spirv64/asin.cpp (+19)
  • (added) libc/src/math/spirv64/asinf.cpp (+19)
  • (added) libc/src/math/spirv64/asinh.cpp (+19)
  • (added) libc/src/math/spirv64/asinhf.cpp (+19)
  • (added) libc/src/math/spirv64/atan.cpp (+19)
  • (added) libc/src/math/spirv64/atan2.cpp (+21)
  • (added) libc/src/math/spirv64/atan2f.cpp (+21)
  • (added) libc/src/math/spirv64/atanf.cpp (+19)
  • (added) libc/src/math/spirv64/atanh.cpp (+19)
  • (added) libc/src/math/spirv64/atanhf.cpp (+19)
  • (added) libc/src/math/spirv64/ceil.cpp (+17)
  • (added) libc/src/math/spirv64/ceilf.cpp (+17)
  • (added) libc/src/math/spirv64/copysign.cpp (+19)
  • (added) libc/src/math/spirv64/copysignf.cpp (+19)
  • (added) libc/src/math/spirv64/cos.cpp (+19)
  • (added) libc/src/math/spirv64/cosf.cpp (+19)
  • (added) libc/src/math/spirv64/cosh.cpp (+19)
  • (added) libc/src/math/spirv64/coshf.cpp (+19)
  • (added) libc/src/math/spirv64/declarations.h (+91)
  • (added) libc/src/math/spirv64/erf.cpp (+19)
  • (added) libc/src/math/spirv64/erff.cpp (+19)
  • (added) libc/src/math/spirv64/exp.cpp (+19)
  • (added) libc/src/math/spirv64/exp10.cpp (+19)
  • (added) libc/src/math/spirv64/exp10f.cpp (+19)
  • (added) libc/src/math/spirv64/exp2.cpp (+19)
  • (added) libc/src/math/spirv64/exp2f.cpp (+19)
  • (added) libc/src/math/spirv64/expf.cpp (+19)
  • (added) libc/src/math/spirv64/expm1.cpp (+19)
  • (added) libc/src/math/spirv64/expm1f.cpp (+19)
  • (added) libc/src/math/spirv64/fabs.cpp (+17)
  • (added) libc/src/math/spirv64/fabsf.cpp (+17)
  • (added) libc/src/math/spirv64/fdim.cpp (+21)
  • (added) libc/src/math/spirv64/fdimf.cpp (+21)
  • (added) libc/src/math/spirv64/floor.cpp (+17)
  • (added) libc/src/math/spirv64/floorf.cpp (+17)
  • (added) libc/src/math/spirv64/fma.cpp (+19)
  • (added) libc/src/math/spirv64/fmaf.cpp (+19)
  • (added) libc/src/math/spirv64/fmax.cpp (+22)
  • (added) libc/src/math/spirv64/fmaxf.cpp (+20)
  • (added) libc/src/math/spirv64/fmin.cpp (+20)
  • (added) libc/src/math/spirv64/fminf.cpp (+20)
  • (added) libc/src/math/spirv64/fmod.cpp (+19)
  • (added) libc/src/math/spirv64/fmodf.cpp (+19)
  • (added) libc/src/math/spirv64/frexp.cpp (+21)
  • (added) libc/src/math/spirv64/frexpf.cpp (+21)
  • (added) libc/src/math/spirv64/hypot.cpp (+21)
  • (added) libc/src/math/spirv64/hypotf.cpp (+21)
  • (added) libc/src/math/spirv64/ilogb.cpp (+19)
  • (added) libc/src/math/spirv64/ilogbf.cpp (+19)
  • (added) libc/src/math/spirv64/ldexp.cpp (+21)
  • (added) libc/src/math/spirv64/ldexpf.cpp (+21)
  • (added) libc/src/math/spirv64/lgamma.cpp (+19)
  • (added) libc/src/math/spirv64/lgamma_r.cpp (+24)
  • (added) libc/src/math/spirv64/llrint.cpp (+21)
  • (added) libc/src/math/spirv64/llrintf.cpp (+21)
  • (added) libc/src/math/spirv64/log.cpp (+19)
  • (added) libc/src/math/spirv64/log10.cpp (+19)
  • (added) libc/src/math/spirv64/log10f.cpp (+19)
  • (added) libc/src/math/spirv64/log1p.cpp (+19)
  • (added) libc/src/math/spirv64/log1pf.cpp (+19)
  • (added) libc/src/math/spirv64/log2.cpp (+19)
  • (added) libc/src/math/spirv64/log2f.cpp (+19)
  • (added) libc/src/math/spirv64/logb.cpp (+19)
  • (added) libc/src/math/spirv64/logbf.cpp (+19)
  • (added) libc/src/math/spirv64/logf.cpp (+19)
  • (added) libc/src/math/spirv64/lrint.cpp (+21)
  • (added) libc/src/math/spirv64/lrintf.cpp (+21)
  • (added) libc/src/math/spirv64/nearbyint.cpp (+19)
  • (added) libc/src/math/spirv64/nearbyintf.cpp (+19)
  • (added) libc/src/math/spirv64/nextafter.cpp (+21)
  • (added) libc/src/math/spirv64/nextafterf.cpp (+21)
  • (added) libc/src/math/spirv64/platform.h (+55)
  • (added) libc/src/math/spirv64/powf.cpp (+21)
  • (added) libc/src/math/spirv64/powi.cpp (+21)
  • (added) libc/src/math/spirv64/powif.cpp (+21)
  • (added) libc/src/math/spirv64/remainder.cpp (+19)
  • (added) libc/src/math/spirv64/remainderf.cpp (+19)
  • (added) libc/src/math/spirv64/remquo.cpp (+24)
  • (added) libc/src/math/spirv64/remquof.cpp (+24)
  • (added) libc/src/math/spirv64/rint.cpp (+17)
  • (added) libc/src/math/spirv64/rintf.cpp (+17)
  • (added) libc/src/math/spirv64/round.cpp (+17)
  • (added) libc/src/math/spirv64/roundf.cpp (+17)
  • (added) libc/src/math/spirv64/scalbn.cpp (+21)
  • (added) libc/src/math/spirv64/scalbnf.cpp (+21)
  • (added) libc/src/math/spirv64/sin.cpp (+19)
  • (added) libc/src/math/spirv64/sincos.cpp (+21)
  • (added) libc/src/math/spirv64/sincosf.cpp (+21)
  • (added) libc/src/math/spirv64/sinf.cpp (+19)
  • (added) libc/src/math/spirv64/sinh.cpp (+19)
  • (added) libc/src/math/spirv64/sinhf.cpp (+19)
  • (added) libc/src/math/spirv64/sqrt.cpp (+17)
  • (added) libc/src/math/spirv64/sqrtf.cpp (+17)
  • (added) libc/src/math/spirv64/tan.cpp (+19)
  • (added) libc/src/math/spirv64/tanf.cpp (+19)
  • (added) libc/src/math/spirv64/tanh.cpp (+19)
  • (added) libc/src/math/spirv64/tanhf.cpp (+19)
  • (added) libc/src/math/spirv64/tgamma.cpp (+19)
  • (added) libc/src/math/spirv64/tgammaf.cpp (+19)
  • (added) libc/src/math/spirv64/trunc.cpp (+17)
  • (added) libc/src/math/spirv64/truncf.cpp (+17)
  • (added) libc/startup/gpu/spirv64/CMakeLists.txt (+15)
  • (added) libc/startup/gpu/spirv64/start.cpp (+80)
  • (modified) lld/ELF/InputFiles.cpp (+5-1)
  • (modified) offload/DeviceRTL/CMakeLists.txt (+5)
  • (modified) offload/DeviceRTL/include/State.h (+18-9)
  • (modified) offload/DeviceRTL/src/State.cpp (+13-8)
  • (modified) offload/cmake/caches/Offload.cmake (+8-6)
  • (modified) offload/test/offloading/bug64959.c (+1-1)
diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h
index 61f9ef7e3e361..610efa1fe00d9 100644
--- a/clang/lib/Basic/Targets/SPIR.h
+++ b/clang/lib/Basic/Targets/SPIR.h
@@ -399,6 +399,8 @@ class LLVM_LIBRARY_VISIBILITY SPIRV64AMDGCNTargetInfo final
     HasLegalHalfType = true;
     HasFloat16 = true;
     HalfArgsAndReturns = true;
+
+    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
   }
 
   bool hasBFloat16Type() const override { return true; }
diff --git a/libc/cmake/modules/LLVMLibCArchitectures.cmake b/libc/cmake/modules/LLVMLibCArchitectures.cmake
index fbb1091ddabab..8d74f71d5cba0 100644
--- a/libc/cmake/modules/LLVMLibCArchitectures.cmake
+++ b/libc/cmake/modules/LLVMLibCArchitectures.cmake
@@ -49,6 +49,8 @@ function(get_arch_and_system_from_triple triple arch_var sys_var)
     set(target_arch "riscv32")
   elseif(target_arch MATCHES "^riscv64")
     set(target_arch "riscv64")
+  elseif(target_arch MATCHES "^spirv64")
+    set(target_arch "spirv64")
   elseif(target_arch MATCHES "^amdgcn")
     set(target_arch "amdgpu")
   elseif(target_arch MATCHES "^nvptx64")
@@ -160,6 +162,8 @@ elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "riscv32")
   set(LIBC_TARGET_ARCHITECTURE "riscv")
 elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "amdgpu")
   set(LIBC_TARGET_ARCHITECTURE_IS_AMDGPU TRUE)
+elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "spirv64")
+  set(LIBC_TARGET_ARCHITECTURE_IS_SPIRV64 TRUE)
 elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "nvptx")
   set(LIBC_TARGET_ARCHITECTURE_IS_NVPTX TRUE)
 else()
diff --git a/libc/config/gpu/spirv64/config.json b/libc/config/gpu/spirv64/config.json
new file mode 100644
index 0000000000000..d99f48ecbede1
--- /dev/null
+++ b/libc/config/gpu/spirv64/config.json
@@ -0,0 +1,37 @@
+{
+  "errno": {
+    "LIBC_CONF_ERRNO_MODE": {
+      "value": "LIBC_ERRNO_MODE_SHARED"
+    }
+  },
+  "printf": {
+    "LIBC_CONF_PRINTF_DISABLE_FLOAT": {
+      "value": true
+    },
+    "LIBC_CONF_PRINTF_DISABLE_INDEX_MODE": {
+      "value": true
+    },
+    "LIBC_CONF_PRINTF_DISABLE_WRITE_INT": {
+      "value": true
+    },
+    "LIBC_CONF_PRINTF_FLOAT_TO_STR_USE_MEGA_LONG_DOUBLE_TABLE": {
+      "value": false
+    },
+    "LIBC_CONF_PRINTF_DISABLE_STRERROR": {
+      "value": true
+    }
+  },
+  "scanf": {
+    "LIBC_CONF_SCANF_DISABLE_FLOAT": {
+      "value": true
+    },
+    "LIBC_CONF_SCANF_DISABLE_INDEX_MODE": {
+      "value": true
+    }
+  },
+  "math": {
+    "LIBC_CONF_MATH_OPTIMIZATIONS": {
+      "value": "(LIBC_MATH_SKIP_ACCURATE_PASS | LIBC_MATH_SMALL_TABLES | LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)"
+    }
+  }
+}
diff --git a/libc/config/gpu/spirv64/entrypoints.txt b/libc/config/gpu/spirv64/entrypoints.txt
new file mode 100644
index 0000000000000..291d86b4dd587
--- /dev/null
+++ b/libc/config/gpu/spirv64/entrypoints.txt
@@ -0,0 +1,607 @@
+set(TARGET_LIBC_ENTRYPOINTS
+    # assert.h entrypoints
+    libc.src.assert.__assert_fail
+
+    # ctype.h entrypoints
+    libc.src.ctype.isalnum
+    libc.src.ctype.isalnum_l
+    libc.src.ctype.isalpha
+    libc.src.ctype.isalpha_l
+    libc.src.ctype.isascii
+    libc.src.ctype.isblank
+    libc.src.ctype.isblank_l
+    libc.src.ctype.iscntrl
+    libc.src.ctype.iscntrl_l
+    libc.src.ctype.isdigit
+    libc.src.ctype.isdigit_l
+    libc.src.ctype.isgraph
+    libc.src.ctype.isgraph_l
+    libc.src.ctype.islower
+    libc.src.ctype.islower_l
+    libc.src.ctype.isprint
+    libc.src.ctype.isprint_l
+    libc.src.ctype.ispunct
+    libc.src.ctype.ispunct_l
+    libc.src.ctype.isspace
+    libc.src.ctype.isspace_l
+    libc.src.ctype.isupper
+    libc.src.ctype.isupper_l
+    libc.src.ctype.isxdigit
+    libc.src.ctype.isxdigit_l
+    libc.src.ctype.toascii
+    libc.src.ctype.tolower
+    libc.src.ctype.tolower_l
+    libc.src.ctype.toupper
+    libc.src.ctype.toupper_l
+
+    # string.h entrypoints
+    libc.src.string.memccpy
+    libc.src.string.memchr
+    libc.src.string.memcmp
+    libc.src.string.memcpy
+    libc.src.string.memmem
+    libc.src.string.memmove
+    libc.src.string.mempcpy
+    libc.src.string.memrchr
+    libc.src.string.memset
+    libc.src.string.stpcpy
+    libc.src.string.stpncpy
+    libc.src.string.strcasestr
+    libc.src.string.strcat
+    libc.src.string.strchr
+    libc.src.string.strchrnul
+    libc.src.string.strcmp
+    libc.src.string.strcoll
+    libc.src.string.strcoll_l
+    libc.src.string.strcpy
+    libc.src.string.strcspn
+    libc.src.string.strdup
+    libc.src.string.strerror
+    libc.src.string.strlcat
+    libc.src.string.strlcpy
+    libc.src.string.strlen
+    libc.src.string.strncat
+    libc.src.string.strncmp
+    libc.src.string.strncpy
+    libc.src.string.strndup
+    libc.src.string.strnlen
+    libc.src.string.strpbrk
+    libc.src.string.strrchr
+    libc.src.string.strsep
+    libc.src.string.strspn
+    libc.src.string.strstr
+    libc.src.string.strtok
+    libc.src.string.strtok_r
+    libc.src.string.strxfrm
+    libc.src.string.strxfrm_l
+
+    # strings.h entrypoints
+    libc.src.strings.bcmp
+    libc.src.strings.bcopy
+    libc.src.strings.bzero
+    libc.src.strings.index
+    libc.src.strings.rindex
+    libc.src.strings.strcasecmp
+    libc.src.strings.strncasecmp
+
+    # stdbit.h entrypoints
+    libc.src.stdbit.stdc_bit_ceil_uc
+    libc.src.stdbit.stdc_bit_ceil_ui
+    libc.src.stdbit.stdc_bit_ceil_ul
+    libc.src.stdbit.stdc_bit_ceil_ull
+    libc.src.stdbit.stdc_bit_ceil_us
+    libc.src.stdbit.stdc_bit_floor_uc
+    libc.src.stdbit.stdc_bit_floor_ui
+    libc.src.stdbit.stdc_bit_floor_ul
+    libc.src.stdbit.stdc_bit_floor_ull
+    libc.src.stdbit.stdc_bit_floor_us
+    libc.src.stdbit.stdc_bit_width_uc
+    libc.src.stdbit.stdc_bit_width_ui
+    libc.src.stdbit.stdc_bit_width_ul
+    libc.src.stdbit.stdc_bit_width_ull
+    libc.src.stdbit.stdc_bit_width_us
+    libc.src.stdbit.stdc_count_ones_uc
+    libc.src.stdbit.stdc_count_ones_ui
+    libc.src.stdbit.stdc_count_ones_ul
+    libc.src.stdbit.stdc_count_ones_ull
+    libc.src.stdbit.stdc_count_ones_us
+    libc.src.stdbit.stdc_count_zeros_uc
+    libc.src.stdbit.stdc_count_zeros_ui
+    libc.src.stdbit.stdc_count_zeros_ul
+    libc.src.stdbit.stdc_count_zeros_ull
+    libc.src.stdbit.stdc_count_zeros_us
+    libc.src.stdbit.stdc_first_leading_one_uc
+    libc.src.stdbit.stdc_first_leading_one_ui
+    libc.src.stdbit.stdc_first_leading_one_ul
+    libc.src.stdbit.stdc_first_leading_one_ull
+    libc.src.stdbit.stdc_first_leading_one_us
+    libc.src.stdbit.stdc_first_leading_zero_uc
+    libc.src.stdbit.stdc_first_leading_zero_ui
+    libc.src.stdbit.stdc_first_leading_zero_ul
+    libc.src.stdbit.stdc_first_leading_zero_ull
+    libc.src.stdbit.stdc_first_leading_zero_us
+    libc.src.stdbit.stdc_first_trailing_one_uc
+    libc.src.stdbit.stdc_first_trailing_one_ui
+    libc.src.stdbit.stdc_first_trailing_one_ul
+    libc.src.stdbit.stdc_first_trailing_one_ull
+    libc.src.stdbit.stdc_first_trailing_one_us
+    libc.src.stdbit.stdc_first_trailing_zero_uc
+    libc.src.stdbit.stdc_first_trailing_zero_ui
+    libc.src.stdbit.stdc_first_trailing_zero_ul
+    libc.src.stdbit.stdc_first_trailing_zero_ull
+    libc.src.stdbit.stdc_first_trailing_zero_us
+    libc.src.stdbit.stdc_has_single_bit_uc
+    libc.src.stdbit.stdc_has_single_bit_ui
+    libc.src.stdbit.stdc_has_single_bit_ul
+    libc.src.stdbit.stdc_has_single_bit_ull
+    libc.src.stdbit.stdc_has_single_bit_us
+    libc.src.stdbit.stdc_leading_ones_uc
+    libc.src.stdbit.stdc_leading_ones_ui
+    libc.src.stdbit.stdc_leading_ones_ul
+    libc.src.stdbit.stdc_leading_ones_ull
+    libc.src.stdbit.stdc_leading_ones_us
+    libc.src.stdbit.stdc_leading_zeros_uc
+    libc.src.stdbit.stdc_leading_zeros_ui
+    libc.src.stdbit.stdc_leading_zeros_ul
+    libc.src.stdbit.stdc_leading_zeros_ull
+    libc.src.stdbit.stdc_leading_zeros_us
+    libc.src.stdbit.stdc_trailing_ones_uc
+    libc.src.stdbit.stdc_trailing_ones_ui
+    libc.src.stdbit.stdc_trailing_ones_ul
+    libc.src.stdbit.stdc_trailing_ones_ull
+    libc.src.stdbit.stdc_trailing_ones_us
+    libc.src.stdbit.stdc_trailing_zeros_uc
+    libc.src.stdbit.stdc_trailing_zeros_ui
+    libc.src.stdbit.stdc_trailing_zeros_ul
+    libc.src.stdbit.stdc_trailing_zeros_ull
+    libc.src.stdbit.stdc_trailing_zeros_us
+
+    # stdlib.h entrypoints
+    libc.src.stdlib._Exit
+    libc.src.stdlib.abort
+    libc.src.stdlib.abs
+    libc.src.stdlib.atexit
+    libc.src.stdlib.atof
+    libc.src.stdlib.atoi
+    libc.src.stdlib.atol
+    libc.src.stdlib.atoll
+    libc.src.stdlib.bsearch
+    libc.src.stdlib.div
+    libc.src.stdlib.exit
+    libc.src.stdlib.labs
+    libc.src.stdlib.ldiv
+    libc.src.stdlib.llabs
+    libc.src.stdlib.lldiv
+    libc.src.stdlib.qsort
+    libc.src.stdlib.qsort_r
+    libc.src.stdlib.rand
+    libc.src.stdlib.srand
+    libc.src.stdlib.strtod
+    libc.src.stdlib.strtod_l
+    libc.src.stdlib.strtof
+    libc.src.stdlib.strtof_l
+    libc.src.stdlib.strtol
+    libc.src.stdlib.strtol_l
+    libc.src.stdlib.strtold
+    libc.src.stdlib.strtold_l
+    libc.src.stdlib.strtoll
+    libc.src.stdlib.strtoll_l
+    libc.src.stdlib.strtoul
+    libc.src.stdlib.strtoul_l
+    libc.src.stdlib.strtoull
+    libc.src.stdlib.strtoull_l
+    libc.src.stdlib.at_quick_exit
+    libc.src.stdlib.quick_exit
+    libc.src.stdlib.getenv
+    libc.src.stdlib.system
+
+    # TODO: Implement these correctly
+    libc.src.stdlib.aligned_alloc
+    libc.src.stdlib.calloc
+    libc.src.stdlib.free
+    libc.src.stdlib.malloc
+    libc.src.stdlib.realloc
+
+    # errno.h entrypoints
+    libc.src.errno.errno
+
+    # stdio.h entrypoints
+    libc.src.stdio.clearerr
+    libc.src.stdio.fclose
+    libc.src.stdio.printf
+    libc.src.stdio.vprintf
+    libc.src.stdio.fprintf
+    libc.src.stdio.vfprintf
+    libc.src.stdio.snprintf
+    libc.src.stdio.sprintf
+    libc.src.stdio.vsnprintf
+    libc.src.stdio.vsprintf
+    libc.src.stdio.asprintf
+    libc.src.stdio.vasprintf
+    libc.src.stdio.scanf
+    libc.src.stdio.vscanf
+    libc.src.stdio.fscanf
+    libc.src.stdio.vfscanf
+    libc.src.stdio.sscanf
+    libc.src.stdio.vsscanf
+    libc.src.stdio.feof
+    libc.src.stdio.ferror
+    libc.src.stdio.fflush
+    libc.src.stdio.fgetc
+    libc.src.stdio.fgets
+    libc.src.stdio.fopen
+    libc.src.stdio.fputc
+    libc.src.stdio.fputs
+    libc.src.stdio.fread
+    libc.src.stdio.fseek
+    libc.src.stdio.ftell
+    libc.src.stdio.fwrite
+    libc.src.stdio.getc
+    libc.src.stdio.getchar
+    libc.src.stdio.putc
+    libc.src.stdio.putchar
+    libc.src.stdio.puts
+    libc.src.stdio.remove
+    libc.src.stdio.rename
+    libc.src.stdio.stderr
+    libc.src.stdio.stdin
+    libc.src.stdio.stdout
+    libc.src.stdio.ungetc
+
+    # inttypes.h entrypoints
+    libc.src.inttypes.imaxabs
+    libc.src.inttypes.imaxdiv
+    libc.src.inttypes.strtoimax
+    libc.src.inttypes.strtoumax
+
+    # time.h entrypoints
+    libc.src.time.clock
+    libc.src.time.clock_gettime
+    libc.src.time.timespec_get
+    libc.src.time.nanosleep
+    libc.src.time.strftime
+    libc.src.time.strftime_l
+
+    # wchar.h entrypoints
+    libc.src.wchar.wcslen
+    libc.src.wchar.wctob
+
+    # locale.h entrypoints
+    libc.src.locale.localeconv
+    libc.src.locale.duplocale
+    libc.src.locale.freelocale
+    libc.src.locale.localeconv
+    libc.src.locale.newlocale
+    libc.src.locale.setlocale
+    libc.src.locale.uselocale
+)
+
+set(TARGET_LIBM_ENTRYPOINTS
+    # math.h entrypoints
+    libc.src.math.acos
+    libc.src.math.acosf
+    libc.src.math.acosh
+    libc.src.math.acoshf
+    libc.src.math.asin
+    libc.src.math.asinf
+    libc.src.math.asinh
+    libc.src.math.asinhf
+    libc.src.math.atan
+    libc.src.math.atan2
+    libc.src.math.atan2f
+    libc.src.math.atan2l
+    libc.src.math.atanf
+    libc.src.math.atanh
+    libc.src.math.atanhf
+    libc.src.math.canonicalize
+    libc.src.math.canonicalizef
+    libc.src.math.canonicalizel
+    libc.src.math.cbrt
+    libc.src.math.cbrtf
+    libc.src.math.ceil
+    libc.src.math.ceilf
+    libc.src.math.ceill
+    libc.src.math.copysign
+    libc.src.math.copysignf
+    libc.src.math.copysignl
+    libc.src.math.cos
+    libc.src.math.cosf
+    libc.src.math.cosh
+    libc.src.math.coshf
+    libc.src.math.cospif
+    libc.src.math.ddivl
+    libc.src.math.dfmal
+    libc.src.math.dmull
+    libc.src.math.dsqrtl
+    libc.src.math.erf
+    libc.src.math.erff
+    libc.src.math.exp
+    libc.src.math.exp10
+    libc.src.math.exp10f
+    libc.src.math.exp2
+    libc.src.math.exp2f
+    libc.src.math.exp2m1f
+    libc.src.math.expf
+    libc.src.math.expm1
+    libc.src.math.expm1f
+    libc.src.math.fabs
+    libc.src.math.fabsf
+    libc.src.math.fabsl
+    libc.src.math.fadd
+    libc.src.math.faddl
+    libc.src.math.fdim
+    libc.src.math.fdimf
+    libc.src.math.fdiml
+    libc.src.math.fdiv
+    libc.src.math.fdivl
+    libc.src.math.ffma
+    libc.src.math.ffmal
+    libc.src.math.floor
+    libc.src.math.floorf
+    libc.src.math.floorl
+    libc.src.math.fma
+    libc.src.math.fmaf
+    libc.src.math.fmax
+    libc.src.math.fmaxf
+    libc.src.math.fmaximum
+    libc.src.math.fmaximumf
+    libc.src.math.fmaximuml
+    libc.src.math.fmaximum_mag
+    libc.src.math.fmaximum_magf
+    libc.src.math.fmaximum_magl
+    libc.src.math.fmaximum_mag_num
+    libc.src.math.fmaximum_mag_numf
+    libc.src.math.fmaximum_mag_numl
+    libc.src.math.fmaximum_num
+    libc.src.math.fmaximum_numf
+    libc.src.math.fmaximum_numl
+    libc.src.math.fmaxl
+    libc.src.math.fmin
+    libc.src.math.fminf
+    libc.src.math.fminimum
+    libc.src.math.fminimumf
+    libc.src.math.fminimuml
+    libc.src.math.fminimum_mag
+    libc.src.math.fminimum_magf
+    libc.src.math.fminimum_magl
+    libc.src.math.fminimum_mag_num
+    libc.src.math.fminimum_mag_numf
+    libc.src.math.fminimum_mag_numl
+    libc.src.math.fminimum_num
+    libc.src.math.fminimum_numf
+    libc.src.math.fminimum_numl
+    libc.src.math.fminl
+    libc.src.math.fmod
+    libc.src.math.fmodf
+    libc.src.math.fmodl
+    libc.src.math.fmul
+    libc.src.math.fmull
+    libc.src.math.frexp
+    libc.src.math.frexpf
+    libc.src.math.frexpl
+    libc.src.math.fromfp
+    libc.src.math.fromfpf
+    libc.src.math.fromfpl
+    libc.src.math.fromfpx
+    libc.src.math.fromfpxf
+    libc.src.math.fromfpxl
+    libc.src.math.fsqrt
+    libc.src.math.fsqrtl
+    libc.src.math.fsub
+    libc.src.math.fsubl
+    libc.src.math.getpayload
+    libc.src.math.getpayloadf
+    libc.src.math.getpayloadl
+    libc.src.math.hypot
+    libc.src.math.hypotf
+    libc.src.math.ilogb
+    libc.src.math.ilogbf
+    libc.src.math.ilogbl
+    libc.src.math.isnan
+    libc.src.math.isnanf
+    libc.src.math.isnanl
+    libc.src.math.ldexp
+    libc.src.math.ldexpf
+    libc.src.math.ldexpl
+    libc.src.math.lgamma
+    libc.src.math.lgamma_r
+    libc.src.math.llogb
+    libc.src.math.llogbf
+    libc.src.math.llogbl
+    libc.src.math.llrint
+    libc.src.math.llrintf
+    libc.src.math.llrintl
+    libc.src.math.llround
+    libc.src.math.llroundf
+    libc.src.math.llroundl
+    libc.src.math.log
+    libc.src.math.log10
+    libc.src.math.log10f
+    libc.src.math.log1p
+    libc.src.math.log1pf
+    libc.src.math.log2
+    libc.src.math.log2f
+    libc.src.math.logb
+    libc.src.math.logbf
+    libc.src.math.logbl
+    libc.src.math.logf
+    libc.src.math.lrint
+    libc.src.math.lrintf
+    libc.src.math.lrintl
+    libc.src.math.lround
+    libc.src.math.lroundf
+    libc.src.math.lroundl
+    libc.src.math.modf
+    libc.src.math.modff
+    libc.src.math.modfl
+    libc.src.math.nan
+    libc.src.math.nanf
+    libc.src.math.nanl
+    libc.src.math.nearbyint
+    libc.src.math.nearbyintf
+    libc.src.math.nearbyintl
+    libc.src.math.nextafter
+    libc.src.math.nextafterf
+    libc.src.math.nextafterl
+    libc.src.math.nextdown
+    libc.src.math.nextdownf
+    libc.src.math.nextdownl
+    libc.src.math.nexttoward
+    libc.src.math.nexttowardf
+    libc.src.math.nexttowardl
+    libc.src.math.nextup
+    libc.src.math.nextupf
+    libc.src.math.nextupl
+    libc.src.math.pow
+    libc.src.math.powf
+    libc.src.math.powi
+    libc.src.math.powif
+    libc.src.math.remainder
+    libc.src.math.remainderf
+    libc.src.math.remainderl
+    libc.src.math.remquo
+    libc.src.math.remquof
+    libc.src.math.remquol
+    libc.src.math.rint
+    libc.src.math.rintf
+    libc.src.math.rintl
+    libc.src.math.roundeven
+    libc.src.math.roundevenf
+    libc.src.math.roundevenl
+    libc.src.math.round
+    libc.src.math.roundf
+    libc.src.math.roundl
+    libc.src.math.scalbln
+    libc.src.math.scalblnf
+    libc.src.math.scalblnl
+    libc.src.math.scalbn
+    libc.src.math.scalbnf
+    libc.src.math.scalbnl
+    libc.src.math.setpayload
+    libc.src.math.setpayloadf
+    libc.src.math.setpayloadl
+    libc.src.math.setpayloadsig
+    libc.src.math.setpayloadsigf
+    libc.src.math.setpayloadsigl
+    libc.src.math.sin
+    libc.src.math.sincos
+    libc.src.math.sincosf
+    libc.src.math.sinf
+    libc.src.math.sinh
+    libc.src.math.sinhf
+    libc.src.math.sinpif
+    libc.src.math.sqrt
+    libc.src.math.sqrtf
+    libc.src.math.sqrtl
+    libc.src.math.tan
+    libc.src.math.tanf
+    libc.src.math.tanh
+    libc.src.math.tanhf
+    libc.src.math.tgamma
+    libc.src.math.tgammaf
+    libc.src.math.totalorder
+    libc.src.math.totalorderf
+    libc.src.math.totalorderl
+    libc.src.math.totalordermag
+    libc.src.math.totalordermagf
+    libc.src.math.totalordermagl
+    libc.src.math.trunc
+    libc.src.math.truncf
+    libc.src.math.truncl
+    libc.src.math.ufromfp
+    libc.src.math.ufromfpf
+    libc.src.math.ufromfpl
+    libc.src.math.ufromfpx
+    libc.src.math.ufromfpxf
+    libc.src.math.ufromfpxl
+)
+
+if(LIBC_TYPES_HAS_FLOAT16)
+  list(APPEND TARGET_LIBM_ENTRYPOINTS
+    # math.h C23 _Float16 entrypoints
+    libc.src.math.canonicalizef16
+    libc.src.math.ceilf16
+    libc.src.math.copysignf16
+    libc.src.math.coshf16
+    libc.src.math.exp10f16
+    libc.src.math.exp10m1f16
+    libc.src.math.exp2f16
+    libc.src.math.expf16
+    libc.src.math.f16add
+    libc.src.math.f16addf
+    libc.src.math.f16addl
+    libc.src.math.f16div
+    libc.src.math.f16divf
+    libc.src.math.f16divl
+    libc.src.math.f16fma
+    libc.src.math.f16fmaf
+    libc.src.math.f16fmal
+    libc.src.math.f16mul
+    libc.src.math.f16mulf
+    libc.src.math.f16mull
+    libc.src.math.f16sqrt
+    libc.src.math.f16sqrtf
+    libc.src.math.f16sqrtl
+    libc.src.math.f16sub
+    libc.src.math.f16subf
+    libc.src.math.f16subl
+    libc.src.math.fabsf16
+    libc.src.math.fdimf16
+    libc.src.math.floorf16
+    libc.src.math.fmaxf16
+    libc.src.math.fmaximum_mag_numf16
+    libc.src.math.fmaximum_magf16
+    libc.src.math.fmaximum_numf16
+    libc.src.math.fmaximumf16
+    libc.src.math.fminf16
+    libc.src.math.fminimum_mag_numf16
+    libc.src.math.fminimum_magf16
+    libc.src.math.fminimum_numf16
+    libc.src.math.fminimumf16
+    libc.src.math.fmodf16
+    libc.src.math.frexpf16
+    libc.src.math.fromfpf16
+    libc.src.math.fromfpxf16
+    libc.src.math.getpayloadf16
+    libc.src.math.ilogbf16
+    libc.src.math.ldexpf16
+    libc.src.math.llogbf16
+    libc.src.math.llrintf16
+    libc.src.math.llroundf16
+    libc.src.math.log10f16
+    libc.src.math.log2f16
+    libc.src.math.logbf16
+    libc.src.math.logf16
+    libc.src.math.lrintf16
+    libc.src.math.lroundf16
+    libc.src.math.modff16
+    libc.src.math.nanf16
+    libc.src.math.nearbyintf16
+    libc.src.math.nextafterf16
+    libc.src.math.nextdownf16
+    libc.src.math.nexttowardf16
+    libc.src.math.nextupf16
+    libc.src.math.remainderf16
+    libc.src.math.remquof16
+    libc.src.math.rintf16
+    libc.src.math.roundevenf16
+    libc.src.math.roundf16
+    libc.src.math.scalblnf16
+    libc.src.math.scalbnf16
+    libc.src.math.setpayloadf16
+    libc.src.math.setpayloadsigf16
+    libc.src.math.sinhf16
+    libc.src.math.sqrtf16
+    libc.src.math.tanhf16
+    libc.src.math.totalorderf16
+    libc.src.math.totalordermagf16
+    libc.src.math.truncf16
+    libc.src.math.ufromfpf16
+    libc.src.math.ufromfpxf16
+  )
+endif()
+
+set(TARGET_LLVMLIBC_ENTRYPOINTS
+  ${TARGET_LIBC_ENTRYPOINTS}
+  ${TARGET_LIBM_ENTRYPOINTS}
+)
diff --git a/libc/config/gpu/spirv64/headers.txt b/libc/config/gpu/s...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Feb 24, 2025

@llvm/pr-subscribers-clang

Author: Jon Chesterfield (JonChesterfield)

Changes

Hopefully we can do better before landing. Posting for discussion.

Didn't learn a huge amount. spirv rejects the clang::amdgpu_kernel annotation and I can't work out how that's supposed to be spelled.

Libc doesn't do anything with address spaces which upsets spirv (unlike openmp which does lots)

The libc build streams bitcode through lld which refuses to do anything with it, but that can be patched.

Port is mostly copying the amdgpu folders to spirv64. Not happy with cmake assuming that spirv64 means amdgpu but also don't understand how to stop it making that assumption.

Lots of libm seems to be dead. I'm hoping Joseph will delete said dead code as it makes this patch look excessively large.

Also doesn't seem ideal to have copy&pasted the config entrypoints stuff.

Don't have a loader, probably reasonable to write one that calls llvm to jit spirv though.


Patch is 136.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/128585.diff

119 Files Affected:

  • (modified) clang/lib/Basic/Targets/SPIR.h (+2)
  • (modified) libc/cmake/modules/LLVMLibCArchitectures.cmake (+4)
  • (added) libc/config/gpu/spirv64/config.json (+37)
  • (added) libc/config/gpu/spirv64/entrypoints.txt (+607)
  • (added) libc/config/gpu/spirv64/headers.txt (+21)
  • (added) libc/src/math/spirv64/CMakeLists.txt (+541)
  • (added) libc/src/math/spirv64/acos.cpp (+19)
  • (added) libc/src/math/spirv64/acosf.cpp (+19)
  • (added) libc/src/math/spirv64/acosh.cpp (+19)
  • (added) libc/src/math/spirv64/acoshf.cpp (+19)
  • (added) libc/src/math/spirv64/asin.cpp (+19)
  • (added) libc/src/math/spirv64/asinf.cpp (+19)
  • (added) libc/src/math/spirv64/asinh.cpp (+19)
  • (added) libc/src/math/spirv64/asinhf.cpp (+19)
  • (added) libc/src/math/spirv64/atan.cpp (+19)
  • (added) libc/src/math/spirv64/atan2.cpp (+21)
  • (added) libc/src/math/spirv64/atan2f.cpp (+21)
  • (added) libc/src/math/spirv64/atanf.cpp (+19)
  • (added) libc/src/math/spirv64/atanh.cpp (+19)
  • (added) libc/src/math/spirv64/atanhf.cpp (+19)
  • (added) libc/src/math/spirv64/ceil.cpp (+17)
  • (added) libc/src/math/spirv64/ceilf.cpp (+17)
  • (added) libc/src/math/spirv64/copysign.cpp (+19)
  • (added) libc/src/math/spirv64/copysignf.cpp (+19)
  • (added) libc/src/math/spirv64/cos.cpp (+19)
  • (added) libc/src/math/spirv64/cosf.cpp (+19)
  • (added) libc/src/math/spirv64/cosh.cpp (+19)
  • (added) libc/src/math/spirv64/coshf.cpp (+19)
  • (added) libc/src/math/spirv64/declarations.h (+91)
  • (added) libc/src/math/spirv64/erf.cpp (+19)
  • (added) libc/src/math/spirv64/erff.cpp (+19)
  • (added) libc/src/math/spirv64/exp.cpp (+19)
  • (added) libc/src/math/spirv64/exp10.cpp (+19)
  • (added) libc/src/math/spirv64/exp10f.cpp (+19)
  • (added) libc/src/math/spirv64/exp2.cpp (+19)
  • (added) libc/src/math/spirv64/exp2f.cpp (+19)
  • (added) libc/src/math/spirv64/expf.cpp (+19)
  • (added) libc/src/math/spirv64/expm1.cpp (+19)
  • (added) libc/src/math/spirv64/expm1f.cpp (+19)
  • (added) libc/src/math/spirv64/fabs.cpp (+17)
  • (added) libc/src/math/spirv64/fabsf.cpp (+17)
  • (added) libc/src/math/spirv64/fdim.cpp (+21)
  • (added) libc/src/math/spirv64/fdimf.cpp (+21)
  • (added) libc/src/math/spirv64/floor.cpp (+17)
  • (added) libc/src/math/spirv64/floorf.cpp (+17)
  • (added) libc/src/math/spirv64/fma.cpp (+19)
  • (added) libc/src/math/spirv64/fmaf.cpp (+19)
  • (added) libc/src/math/spirv64/fmax.cpp (+22)
  • (added) libc/src/math/spirv64/fmaxf.cpp (+20)
  • (added) libc/src/math/spirv64/fmin.cpp (+20)
  • (added) libc/src/math/spirv64/fminf.cpp (+20)
  • (added) libc/src/math/spirv64/fmod.cpp (+19)
  • (added) libc/src/math/spirv64/fmodf.cpp (+19)
  • (added) libc/src/math/spirv64/frexp.cpp (+21)
  • (added) libc/src/math/spirv64/frexpf.cpp (+21)
  • (added) libc/src/math/spirv64/hypot.cpp (+21)
  • (added) libc/src/math/spirv64/hypotf.cpp (+21)
  • (added) libc/src/math/spirv64/ilogb.cpp (+19)
  • (added) libc/src/math/spirv64/ilogbf.cpp (+19)
  • (added) libc/src/math/spirv64/ldexp.cpp (+21)
  • (added) libc/src/math/spirv64/ldexpf.cpp (+21)
  • (added) libc/src/math/spirv64/lgamma.cpp (+19)
  • (added) libc/src/math/spirv64/lgamma_r.cpp (+24)
  • (added) libc/src/math/spirv64/llrint.cpp (+21)
  • (added) libc/src/math/spirv64/llrintf.cpp (+21)
  • (added) libc/src/math/spirv64/log.cpp (+19)
  • (added) libc/src/math/spirv64/log10.cpp (+19)
  • (added) libc/src/math/spirv64/log10f.cpp (+19)
  • (added) libc/src/math/spirv64/log1p.cpp (+19)
  • (added) libc/src/math/spirv64/log1pf.cpp (+19)
  • (added) libc/src/math/spirv64/log2.cpp (+19)
  • (added) libc/src/math/spirv64/log2f.cpp (+19)
  • (added) libc/src/math/spirv64/logb.cpp (+19)
  • (added) libc/src/math/spirv64/logbf.cpp (+19)
  • (added) libc/src/math/spirv64/logf.cpp (+19)
  • (added) libc/src/math/spirv64/lrint.cpp (+21)
  • (added) libc/src/math/spirv64/lrintf.cpp (+21)
  • (added) libc/src/math/spirv64/nearbyint.cpp (+19)
  • (added) libc/src/math/spirv64/nearbyintf.cpp (+19)
  • (added) libc/src/math/spirv64/nextafter.cpp (+21)
  • (added) libc/src/math/spirv64/nextafterf.cpp (+21)
  • (added) libc/src/math/spirv64/platform.h (+55)
  • (added) libc/src/math/spirv64/powf.cpp (+21)
  • (added) libc/src/math/spirv64/powi.cpp (+21)
  • (added) libc/src/math/spirv64/powif.cpp (+21)
  • (added) libc/src/math/spirv64/remainder.cpp (+19)
  • (added) libc/src/math/spirv64/remainderf.cpp (+19)
  • (added) libc/src/math/spirv64/remquo.cpp (+24)
  • (added) libc/src/math/spirv64/remquof.cpp (+24)
  • (added) libc/src/math/spirv64/rint.cpp (+17)
  • (added) libc/src/math/spirv64/rintf.cpp (+17)
  • (added) libc/src/math/spirv64/round.cpp (+17)
  • (added) libc/src/math/spirv64/roundf.cpp (+17)
  • (added) libc/src/math/spirv64/scalbn.cpp (+21)
  • (added) libc/src/math/spirv64/scalbnf.cpp (+21)
  • (added) libc/src/math/spirv64/sin.cpp (+19)
  • (added) libc/src/math/spirv64/sincos.cpp (+21)
  • (added) libc/src/math/spirv64/sincosf.cpp (+21)
  • (added) libc/src/math/spirv64/sinf.cpp (+19)
  • (added) libc/src/math/spirv64/sinh.cpp (+19)
  • (added) libc/src/math/spirv64/sinhf.cpp (+19)
  • (added) libc/src/math/spirv64/sqrt.cpp (+17)
  • (added) libc/src/math/spirv64/sqrtf.cpp (+17)
  • (added) libc/src/math/spirv64/tan.cpp (+19)
  • (added) libc/src/math/spirv64/tanf.cpp (+19)
  • (added) libc/src/math/spirv64/tanh.cpp (+19)
  • (added) libc/src/math/spirv64/tanhf.cpp (+19)
  • (added) libc/src/math/spirv64/tgamma.cpp (+19)
  • (added) libc/src/math/spirv64/tgammaf.cpp (+19)
  • (added) libc/src/math/spirv64/trunc.cpp (+17)
  • (added) libc/src/math/spirv64/truncf.cpp (+17)
  • (added) libc/startup/gpu/spirv64/CMakeLists.txt (+15)
  • (added) libc/startup/gpu/spirv64/start.cpp (+80)
  • (modified) lld/ELF/InputFiles.cpp (+5-1)
  • (modified) offload/DeviceRTL/CMakeLists.txt (+5)
  • (modified) offload/DeviceRTL/include/State.h (+18-9)
  • (modified) offload/DeviceRTL/src/State.cpp (+13-8)
  • (modified) offload/cmake/caches/Offload.cmake (+8-6)
  • (modified) offload/test/offloading/bug64959.c (+1-1)
diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h
index 61f9ef7e3e361..610efa1fe00d9 100644
--- a/clang/lib/Basic/Targets/SPIR.h
+++ b/clang/lib/Basic/Targets/SPIR.h
@@ -399,6 +399,8 @@ class LLVM_LIBRARY_VISIBILITY SPIRV64AMDGCNTargetInfo final
     HasLegalHalfType = true;
     HasFloat16 = true;
     HalfArgsAndReturns = true;
+
+    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
   }
 
   bool hasBFloat16Type() const override { return true; }
diff --git a/libc/cmake/modules/LLVMLibCArchitectures.cmake b/libc/cmake/modules/LLVMLibCArchitectures.cmake
index fbb1091ddabab..8d74f71d5cba0 100644
--- a/libc/cmake/modules/LLVMLibCArchitectures.cmake
+++ b/libc/cmake/modules/LLVMLibCArchitectures.cmake
@@ -49,6 +49,8 @@ function(get_arch_and_system_from_triple triple arch_var sys_var)
     set(target_arch "riscv32")
   elseif(target_arch MATCHES "^riscv64")
     set(target_arch "riscv64")
+  elseif(target_arch MATCHES "^spirv64")
+    set(target_arch "spirv64")
   elseif(target_arch MATCHES "^amdgcn")
     set(target_arch "amdgpu")
   elseif(target_arch MATCHES "^nvptx64")
@@ -160,6 +162,8 @@ elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "riscv32")
   set(LIBC_TARGET_ARCHITECTURE "riscv")
 elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "amdgpu")
   set(LIBC_TARGET_ARCHITECTURE_IS_AMDGPU TRUE)
+elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "spirv64")
+  set(LIBC_TARGET_ARCHITECTURE_IS_SPIRV64 TRUE)
 elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "nvptx")
   set(LIBC_TARGET_ARCHITECTURE_IS_NVPTX TRUE)
 else()
diff --git a/libc/config/gpu/spirv64/config.json b/libc/config/gpu/spirv64/config.json
new file mode 100644
index 0000000000000..d99f48ecbede1
--- /dev/null
+++ b/libc/config/gpu/spirv64/config.json
@@ -0,0 +1,37 @@
+{
+  "errno": {
+    "LIBC_CONF_ERRNO_MODE": {
+      "value": "LIBC_ERRNO_MODE_SHARED"
+    }
+  },
+  "printf": {
+    "LIBC_CONF_PRINTF_DISABLE_FLOAT": {
+      "value": true
+    },
+    "LIBC_CONF_PRINTF_DISABLE_INDEX_MODE": {
+      "value": true
+    },
+    "LIBC_CONF_PRINTF_DISABLE_WRITE_INT": {
+      "value": true
+    },
+    "LIBC_CONF_PRINTF_FLOAT_TO_STR_USE_MEGA_LONG_DOUBLE_TABLE": {
+      "value": false
+    },
+    "LIBC_CONF_PRINTF_DISABLE_STRERROR": {
+      "value": true
+    }
+  },
+  "scanf": {
+    "LIBC_CONF_SCANF_DISABLE_FLOAT": {
+      "value": true
+    },
+    "LIBC_CONF_SCANF_DISABLE_INDEX_MODE": {
+      "value": true
+    }
+  },
+  "math": {
+    "LIBC_CONF_MATH_OPTIMIZATIONS": {
+      "value": "(LIBC_MATH_SKIP_ACCURATE_PASS | LIBC_MATH_SMALL_TABLES | LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)"
+    }
+  }
+}
diff --git a/libc/config/gpu/spirv64/entrypoints.txt b/libc/config/gpu/spirv64/entrypoints.txt
new file mode 100644
index 0000000000000..291d86b4dd587
--- /dev/null
+++ b/libc/config/gpu/spirv64/entrypoints.txt
@@ -0,0 +1,607 @@
+set(TARGET_LIBC_ENTRYPOINTS
+    # assert.h entrypoints
+    libc.src.assert.__assert_fail
+
+    # ctype.h entrypoints
+    libc.src.ctype.isalnum
+    libc.src.ctype.isalnum_l
+    libc.src.ctype.isalpha
+    libc.src.ctype.isalpha_l
+    libc.src.ctype.isascii
+    libc.src.ctype.isblank
+    libc.src.ctype.isblank_l
+    libc.src.ctype.iscntrl
+    libc.src.ctype.iscntrl_l
+    libc.src.ctype.isdigit
+    libc.src.ctype.isdigit_l
+    libc.src.ctype.isgraph
+    libc.src.ctype.isgraph_l
+    libc.src.ctype.islower
+    libc.src.ctype.islower_l
+    libc.src.ctype.isprint
+    libc.src.ctype.isprint_l
+    libc.src.ctype.ispunct
+    libc.src.ctype.ispunct_l
+    libc.src.ctype.isspace
+    libc.src.ctype.isspace_l
+    libc.src.ctype.isupper
+    libc.src.ctype.isupper_l
+    libc.src.ctype.isxdigit
+    libc.src.ctype.isxdigit_l
+    libc.src.ctype.toascii
+    libc.src.ctype.tolower
+    libc.src.ctype.tolower_l
+    libc.src.ctype.toupper
+    libc.src.ctype.toupper_l
+
+    # string.h entrypoints
+    libc.src.string.memccpy
+    libc.src.string.memchr
+    libc.src.string.memcmp
+    libc.src.string.memcpy
+    libc.src.string.memmem
+    libc.src.string.memmove
+    libc.src.string.mempcpy
+    libc.src.string.memrchr
+    libc.src.string.memset
+    libc.src.string.stpcpy
+    libc.src.string.stpncpy
+    libc.src.string.strcasestr
+    libc.src.string.strcat
+    libc.src.string.strchr
+    libc.src.string.strchrnul
+    libc.src.string.strcmp
+    libc.src.string.strcoll
+    libc.src.string.strcoll_l
+    libc.src.string.strcpy
+    libc.src.string.strcspn
+    libc.src.string.strdup
+    libc.src.string.strerror
+    libc.src.string.strlcat
+    libc.src.string.strlcpy
+    libc.src.string.strlen
+    libc.src.string.strncat
+    libc.src.string.strncmp
+    libc.src.string.strncpy
+    libc.src.string.strndup
+    libc.src.string.strnlen
+    libc.src.string.strpbrk
+    libc.src.string.strrchr
+    libc.src.string.strsep
+    libc.src.string.strspn
+    libc.src.string.strstr
+    libc.src.string.strtok
+    libc.src.string.strtok_r
+    libc.src.string.strxfrm
+    libc.src.string.strxfrm_l
+
+    # strings.h entrypoints
+    libc.src.strings.bcmp
+    libc.src.strings.bcopy
+    libc.src.strings.bzero
+    libc.src.strings.index
+    libc.src.strings.rindex
+    libc.src.strings.strcasecmp
+    libc.src.strings.strncasecmp
+
+    # stdbit.h entrypoints
+    libc.src.stdbit.stdc_bit_ceil_uc
+    libc.src.stdbit.stdc_bit_ceil_ui
+    libc.src.stdbit.stdc_bit_ceil_ul
+    libc.src.stdbit.stdc_bit_ceil_ull
+    libc.src.stdbit.stdc_bit_ceil_us
+    libc.src.stdbit.stdc_bit_floor_uc
+    libc.src.stdbit.stdc_bit_floor_ui
+    libc.src.stdbit.stdc_bit_floor_ul
+    libc.src.stdbit.stdc_bit_floor_ull
+    libc.src.stdbit.stdc_bit_floor_us
+    libc.src.stdbit.stdc_bit_width_uc
+    libc.src.stdbit.stdc_bit_width_ui
+    libc.src.stdbit.stdc_bit_width_ul
+    libc.src.stdbit.stdc_bit_width_ull
+    libc.src.stdbit.stdc_bit_width_us
+    libc.src.stdbit.stdc_count_ones_uc
+    libc.src.stdbit.stdc_count_ones_ui
+    libc.src.stdbit.stdc_count_ones_ul
+    libc.src.stdbit.stdc_count_ones_ull
+    libc.src.stdbit.stdc_count_ones_us
+    libc.src.stdbit.stdc_count_zeros_uc
+    libc.src.stdbit.stdc_count_zeros_ui
+    libc.src.stdbit.stdc_count_zeros_ul
+    libc.src.stdbit.stdc_count_zeros_ull
+    libc.src.stdbit.stdc_count_zeros_us
+    libc.src.stdbit.stdc_first_leading_one_uc
+    libc.src.stdbit.stdc_first_leading_one_ui
+    libc.src.stdbit.stdc_first_leading_one_ul
+    libc.src.stdbit.stdc_first_leading_one_ull
+    libc.src.stdbit.stdc_first_leading_one_us
+    libc.src.stdbit.stdc_first_leading_zero_uc
+    libc.src.stdbit.stdc_first_leading_zero_ui
+    libc.src.stdbit.stdc_first_leading_zero_ul
+    libc.src.stdbit.stdc_first_leading_zero_ull
+    libc.src.stdbit.stdc_first_leading_zero_us
+    libc.src.stdbit.stdc_first_trailing_one_uc
+    libc.src.stdbit.stdc_first_trailing_one_ui
+    libc.src.stdbit.stdc_first_trailing_one_ul
+    libc.src.stdbit.stdc_first_trailing_one_ull
+    libc.src.stdbit.stdc_first_trailing_one_us
+    libc.src.stdbit.stdc_first_trailing_zero_uc
+    libc.src.stdbit.stdc_first_trailing_zero_ui
+    libc.src.stdbit.stdc_first_trailing_zero_ul
+    libc.src.stdbit.stdc_first_trailing_zero_ull
+    libc.src.stdbit.stdc_first_trailing_zero_us
+    libc.src.stdbit.stdc_has_single_bit_uc
+    libc.src.stdbit.stdc_has_single_bit_ui
+    libc.src.stdbit.stdc_has_single_bit_ul
+    libc.src.stdbit.stdc_has_single_bit_ull
+    libc.src.stdbit.stdc_has_single_bit_us
+    libc.src.stdbit.stdc_leading_ones_uc
+    libc.src.stdbit.stdc_leading_ones_ui
+    libc.src.stdbit.stdc_leading_ones_ul
+    libc.src.stdbit.stdc_leading_ones_ull
+    libc.src.stdbit.stdc_leading_ones_us
+    libc.src.stdbit.stdc_leading_zeros_uc
+    libc.src.stdbit.stdc_leading_zeros_ui
+    libc.src.stdbit.stdc_leading_zeros_ul
+    libc.src.stdbit.stdc_leading_zeros_ull
+    libc.src.stdbit.stdc_leading_zeros_us
+    libc.src.stdbit.stdc_trailing_ones_uc
+    libc.src.stdbit.stdc_trailing_ones_ui
+    libc.src.stdbit.stdc_trailing_ones_ul
+    libc.src.stdbit.stdc_trailing_ones_ull
+    libc.src.stdbit.stdc_trailing_ones_us
+    libc.src.stdbit.stdc_trailing_zeros_uc
+    libc.src.stdbit.stdc_trailing_zeros_ui
+    libc.src.stdbit.stdc_trailing_zeros_ul
+    libc.src.stdbit.stdc_trailing_zeros_ull
+    libc.src.stdbit.stdc_trailing_zeros_us
+
+    # stdlib.h entrypoints
+    libc.src.stdlib._Exit
+    libc.src.stdlib.abort
+    libc.src.stdlib.abs
+    libc.src.stdlib.atexit
+    libc.src.stdlib.atof
+    libc.src.stdlib.atoi
+    libc.src.stdlib.atol
+    libc.src.stdlib.atoll
+    libc.src.stdlib.bsearch
+    libc.src.stdlib.div
+    libc.src.stdlib.exit
+    libc.src.stdlib.labs
+    libc.src.stdlib.ldiv
+    libc.src.stdlib.llabs
+    libc.src.stdlib.lldiv
+    libc.src.stdlib.qsort
+    libc.src.stdlib.qsort_r
+    libc.src.stdlib.rand
+    libc.src.stdlib.srand
+    libc.src.stdlib.strtod
+    libc.src.stdlib.strtod_l
+    libc.src.stdlib.strtof
+    libc.src.stdlib.strtof_l
+    libc.src.stdlib.strtol
+    libc.src.stdlib.strtol_l
+    libc.src.stdlib.strtold
+    libc.src.stdlib.strtold_l
+    libc.src.stdlib.strtoll
+    libc.src.stdlib.strtoll_l
+    libc.src.stdlib.strtoul
+    libc.src.stdlib.strtoul_l
+    libc.src.stdlib.strtoull
+    libc.src.stdlib.strtoull_l
+    libc.src.stdlib.at_quick_exit
+    libc.src.stdlib.quick_exit
+    libc.src.stdlib.getenv
+    libc.src.stdlib.system
+
+    # TODO: Implement these correctly
+    libc.src.stdlib.aligned_alloc
+    libc.src.stdlib.calloc
+    libc.src.stdlib.free
+    libc.src.stdlib.malloc
+    libc.src.stdlib.realloc
+
+    # errno.h entrypoints
+    libc.src.errno.errno
+
+    # stdio.h entrypoints
+    libc.src.stdio.clearerr
+    libc.src.stdio.fclose
+    libc.src.stdio.printf
+    libc.src.stdio.vprintf
+    libc.src.stdio.fprintf
+    libc.src.stdio.vfprintf
+    libc.src.stdio.snprintf
+    libc.src.stdio.sprintf
+    libc.src.stdio.vsnprintf
+    libc.src.stdio.vsprintf
+    libc.src.stdio.asprintf
+    libc.src.stdio.vasprintf
+    libc.src.stdio.scanf
+    libc.src.stdio.vscanf
+    libc.src.stdio.fscanf
+    libc.src.stdio.vfscanf
+    libc.src.stdio.sscanf
+    libc.src.stdio.vsscanf
+    libc.src.stdio.feof
+    libc.src.stdio.ferror
+    libc.src.stdio.fflush
+    libc.src.stdio.fgetc
+    libc.src.stdio.fgets
+    libc.src.stdio.fopen
+    libc.src.stdio.fputc
+    libc.src.stdio.fputs
+    libc.src.stdio.fread
+    libc.src.stdio.fseek
+    libc.src.stdio.ftell
+    libc.src.stdio.fwrite
+    libc.src.stdio.getc
+    libc.src.stdio.getchar
+    libc.src.stdio.putc
+    libc.src.stdio.putchar
+    libc.src.stdio.puts
+    libc.src.stdio.remove
+    libc.src.stdio.rename
+    libc.src.stdio.stderr
+    libc.src.stdio.stdin
+    libc.src.stdio.stdout
+    libc.src.stdio.ungetc
+
+    # inttypes.h entrypoints
+    libc.src.inttypes.imaxabs
+    libc.src.inttypes.imaxdiv
+    libc.src.inttypes.strtoimax
+    libc.src.inttypes.strtoumax
+
+    # time.h entrypoints
+    libc.src.time.clock
+    libc.src.time.clock_gettime
+    libc.src.time.timespec_get
+    libc.src.time.nanosleep
+    libc.src.time.strftime
+    libc.src.time.strftime_l
+
+    # wchar.h entrypoints
+    libc.src.wchar.wcslen
+    libc.src.wchar.wctob
+
+    # locale.h entrypoints
+    libc.src.locale.localeconv
+    libc.src.locale.duplocale
+    libc.src.locale.freelocale
+    libc.src.locale.localeconv
+    libc.src.locale.newlocale
+    libc.src.locale.setlocale
+    libc.src.locale.uselocale
+)
+
+set(TARGET_LIBM_ENTRYPOINTS
+    # math.h entrypoints
+    libc.src.math.acos
+    libc.src.math.acosf
+    libc.src.math.acosh
+    libc.src.math.acoshf
+    libc.src.math.asin
+    libc.src.math.asinf
+    libc.src.math.asinh
+    libc.src.math.asinhf
+    libc.src.math.atan
+    libc.src.math.atan2
+    libc.src.math.atan2f
+    libc.src.math.atan2l
+    libc.src.math.atanf
+    libc.src.math.atanh
+    libc.src.math.atanhf
+    libc.src.math.canonicalize
+    libc.src.math.canonicalizef
+    libc.src.math.canonicalizel
+    libc.src.math.cbrt
+    libc.src.math.cbrtf
+    libc.src.math.ceil
+    libc.src.math.ceilf
+    libc.src.math.ceill
+    libc.src.math.copysign
+    libc.src.math.copysignf
+    libc.src.math.copysignl
+    libc.src.math.cos
+    libc.src.math.cosf
+    libc.src.math.cosh
+    libc.src.math.coshf
+    libc.src.math.cospif
+    libc.src.math.ddivl
+    libc.src.math.dfmal
+    libc.src.math.dmull
+    libc.src.math.dsqrtl
+    libc.src.math.erf
+    libc.src.math.erff
+    libc.src.math.exp
+    libc.src.math.exp10
+    libc.src.math.exp10f
+    libc.src.math.exp2
+    libc.src.math.exp2f
+    libc.src.math.exp2m1f
+    libc.src.math.expf
+    libc.src.math.expm1
+    libc.src.math.expm1f
+    libc.src.math.fabs
+    libc.src.math.fabsf
+    libc.src.math.fabsl
+    libc.src.math.fadd
+    libc.src.math.faddl
+    libc.src.math.fdim
+    libc.src.math.fdimf
+    libc.src.math.fdiml
+    libc.src.math.fdiv
+    libc.src.math.fdivl
+    libc.src.math.ffma
+    libc.src.math.ffmal
+    libc.src.math.floor
+    libc.src.math.floorf
+    libc.src.math.floorl
+    libc.src.math.fma
+    libc.src.math.fmaf
+    libc.src.math.fmax
+    libc.src.math.fmaxf
+    libc.src.math.fmaximum
+    libc.src.math.fmaximumf
+    libc.src.math.fmaximuml
+    libc.src.math.fmaximum_mag
+    libc.src.math.fmaximum_magf
+    libc.src.math.fmaximum_magl
+    libc.src.math.fmaximum_mag_num
+    libc.src.math.fmaximum_mag_numf
+    libc.src.math.fmaximum_mag_numl
+    libc.src.math.fmaximum_num
+    libc.src.math.fmaximum_numf
+    libc.src.math.fmaximum_numl
+    libc.src.math.fmaxl
+    libc.src.math.fmin
+    libc.src.math.fminf
+    libc.src.math.fminimum
+    libc.src.math.fminimumf
+    libc.src.math.fminimuml
+    libc.src.math.fminimum_mag
+    libc.src.math.fminimum_magf
+    libc.src.math.fminimum_magl
+    libc.src.math.fminimum_mag_num
+    libc.src.math.fminimum_mag_numf
+    libc.src.math.fminimum_mag_numl
+    libc.src.math.fminimum_num
+    libc.src.math.fminimum_numf
+    libc.src.math.fminimum_numl
+    libc.src.math.fminl
+    libc.src.math.fmod
+    libc.src.math.fmodf
+    libc.src.math.fmodl
+    libc.src.math.fmul
+    libc.src.math.fmull
+    libc.src.math.frexp
+    libc.src.math.frexpf
+    libc.src.math.frexpl
+    libc.src.math.fromfp
+    libc.src.math.fromfpf
+    libc.src.math.fromfpl
+    libc.src.math.fromfpx
+    libc.src.math.fromfpxf
+    libc.src.math.fromfpxl
+    libc.src.math.fsqrt
+    libc.src.math.fsqrtl
+    libc.src.math.fsub
+    libc.src.math.fsubl
+    libc.src.math.getpayload
+    libc.src.math.getpayloadf
+    libc.src.math.getpayloadl
+    libc.src.math.hypot
+    libc.src.math.hypotf
+    libc.src.math.ilogb
+    libc.src.math.ilogbf
+    libc.src.math.ilogbl
+    libc.src.math.isnan
+    libc.src.math.isnanf
+    libc.src.math.isnanl
+    libc.src.math.ldexp
+    libc.src.math.ldexpf
+    libc.src.math.ldexpl
+    libc.src.math.lgamma
+    libc.src.math.lgamma_r
+    libc.src.math.llogb
+    libc.src.math.llogbf
+    libc.src.math.llogbl
+    libc.src.math.llrint
+    libc.src.math.llrintf
+    libc.src.math.llrintl
+    libc.src.math.llround
+    libc.src.math.llroundf
+    libc.src.math.llroundl
+    libc.src.math.log
+    libc.src.math.log10
+    libc.src.math.log10f
+    libc.src.math.log1p
+    libc.src.math.log1pf
+    libc.src.math.log2
+    libc.src.math.log2f
+    libc.src.math.logb
+    libc.src.math.logbf
+    libc.src.math.logbl
+    libc.src.math.logf
+    libc.src.math.lrint
+    libc.src.math.lrintf
+    libc.src.math.lrintl
+    libc.src.math.lround
+    libc.src.math.lroundf
+    libc.src.math.lroundl
+    libc.src.math.modf
+    libc.src.math.modff
+    libc.src.math.modfl
+    libc.src.math.nan
+    libc.src.math.nanf
+    libc.src.math.nanl
+    libc.src.math.nearbyint
+    libc.src.math.nearbyintf
+    libc.src.math.nearbyintl
+    libc.src.math.nextafter
+    libc.src.math.nextafterf
+    libc.src.math.nextafterl
+    libc.src.math.nextdown
+    libc.src.math.nextdownf
+    libc.src.math.nextdownl
+    libc.src.math.nexttoward
+    libc.src.math.nexttowardf
+    libc.src.math.nexttowardl
+    libc.src.math.nextup
+    libc.src.math.nextupf
+    libc.src.math.nextupl
+    libc.src.math.pow
+    libc.src.math.powf
+    libc.src.math.powi
+    libc.src.math.powif
+    libc.src.math.remainder
+    libc.src.math.remainderf
+    libc.src.math.remainderl
+    libc.src.math.remquo
+    libc.src.math.remquof
+    libc.src.math.remquol
+    libc.src.math.rint
+    libc.src.math.rintf
+    libc.src.math.rintl
+    libc.src.math.roundeven
+    libc.src.math.roundevenf
+    libc.src.math.roundevenl
+    libc.src.math.round
+    libc.src.math.roundf
+    libc.src.math.roundl
+    libc.src.math.scalbln
+    libc.src.math.scalblnf
+    libc.src.math.scalblnl
+    libc.src.math.scalbn
+    libc.src.math.scalbnf
+    libc.src.math.scalbnl
+    libc.src.math.setpayload
+    libc.src.math.setpayloadf
+    libc.src.math.setpayloadl
+    libc.src.math.setpayloadsig
+    libc.src.math.setpayloadsigf
+    libc.src.math.setpayloadsigl
+    libc.src.math.sin
+    libc.src.math.sincos
+    libc.src.math.sincosf
+    libc.src.math.sinf
+    libc.src.math.sinh
+    libc.src.math.sinhf
+    libc.src.math.sinpif
+    libc.src.math.sqrt
+    libc.src.math.sqrtf
+    libc.src.math.sqrtl
+    libc.src.math.tan
+    libc.src.math.tanf
+    libc.src.math.tanh
+    libc.src.math.tanhf
+    libc.src.math.tgamma
+    libc.src.math.tgammaf
+    libc.src.math.totalorder
+    libc.src.math.totalorderf
+    libc.src.math.totalorderl
+    libc.src.math.totalordermag
+    libc.src.math.totalordermagf
+    libc.src.math.totalordermagl
+    libc.src.math.trunc
+    libc.src.math.truncf
+    libc.src.math.truncl
+    libc.src.math.ufromfp
+    libc.src.math.ufromfpf
+    libc.src.math.ufromfpl
+    libc.src.math.ufromfpx
+    libc.src.math.ufromfpxf
+    libc.src.math.ufromfpxl
+)
+
+if(LIBC_TYPES_HAS_FLOAT16)
+  list(APPEND TARGET_LIBM_ENTRYPOINTS
+    # math.h C23 _Float16 entrypoints
+    libc.src.math.canonicalizef16
+    libc.src.math.ceilf16
+    libc.src.math.copysignf16
+    libc.src.math.coshf16
+    libc.src.math.exp10f16
+    libc.src.math.exp10m1f16
+    libc.src.math.exp2f16
+    libc.src.math.expf16
+    libc.src.math.f16add
+    libc.src.math.f16addf
+    libc.src.math.f16addl
+    libc.src.math.f16div
+    libc.src.math.f16divf
+    libc.src.math.f16divl
+    libc.src.math.f16fma
+    libc.src.math.f16fmaf
+    libc.src.math.f16fmal
+    libc.src.math.f16mul
+    libc.src.math.f16mulf
+    libc.src.math.f16mull
+    libc.src.math.f16sqrt
+    libc.src.math.f16sqrtf
+    libc.src.math.f16sqrtl
+    libc.src.math.f16sub
+    libc.src.math.f16subf
+    libc.src.math.f16subl
+    libc.src.math.fabsf16
+    libc.src.math.fdimf16
+    libc.src.math.floorf16
+    libc.src.math.fmaxf16
+    libc.src.math.fmaximum_mag_numf16
+    libc.src.math.fmaximum_magf16
+    libc.src.math.fmaximum_numf16
+    libc.src.math.fmaximumf16
+    libc.src.math.fminf16
+    libc.src.math.fminimum_mag_numf16
+    libc.src.math.fminimum_magf16
+    libc.src.math.fminimum_numf16
+    libc.src.math.fminimumf16
+    libc.src.math.fmodf16
+    libc.src.math.frexpf16
+    libc.src.math.fromfpf16
+    libc.src.math.fromfpxf16
+    libc.src.math.getpayloadf16
+    libc.src.math.ilogbf16
+    libc.src.math.ldexpf16
+    libc.src.math.llogbf16
+    libc.src.math.llrintf16
+    libc.src.math.llroundf16
+    libc.src.math.log10f16
+    libc.src.math.log2f16
+    libc.src.math.logbf16
+    libc.src.math.logf16
+    libc.src.math.lrintf16
+    libc.src.math.lroundf16
+    libc.src.math.modff16
+    libc.src.math.nanf16
+    libc.src.math.nearbyintf16
+    libc.src.math.nextafterf16
+    libc.src.math.nextdownf16
+    libc.src.math.nexttowardf16
+    libc.src.math.nextupf16
+    libc.src.math.remainderf16
+    libc.src.math.remquof16
+    libc.src.math.rintf16
+    libc.src.math.roundevenf16
+    libc.src.math.roundf16
+    libc.src.math.scalblnf16
+    libc.src.math.scalbnf16
+    libc.src.math.setpayloadf16
+    libc.src.math.setpayloadsigf16
+    libc.src.math.sinhf16
+    libc.src.math.sqrtf16
+    libc.src.math.tanhf16
+    libc.src.math.totalorderf16
+    libc.src.math.totalordermagf16
+    libc.src.math.truncf16
+    libc.src.math.ufromfpf16
+    libc.src.math.ufromfpxf16
+  )
+endif()
+
+set(TARGET_LLVMLIBC_ENTRYPOINTS
+  ${TARGET_LIBC_ENTRYPOINTS}
+  ${TARGET_LIBM_ENTRYPOINTS}
+)
diff --git a/libc/config/gpu/spirv64/headers.txt b/libc/config/gpu/s...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Feb 24, 2025

@llvm/pr-subscribers-lld

Author: Jon Chesterfield (JonChesterfield)

Changes

Hopefully we can do better before landing. Posting for discussion.

Didn't learn a huge amount. spirv rejects the clang::amdgpu_kernel annotation and I can't work out how that's supposed to be spelled.

Libc doesn't do anything with address spaces which upsets spirv (unlike openmp which does lots)

The libc build streams bitcode through lld which refuses to do anything with it, but that can be patched.

Port is mostly copying the amdgpu folders to spirv64. Not happy with cmake assuming that spirv64 means amdgpu but also don't understand how to stop it making that assumption.

Lots of libm seems to be dead. I'm hoping Joseph will delete said dead code as it makes this patch look excessively large.

Also doesn't seem ideal to have copy&pasted the config entrypoints stuff.

Don't have a loader, probably reasonable to write one that calls llvm to jit spirv though.


Patch is 136.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/128585.diff

119 Files Affected:

  • (modified) clang/lib/Basic/Targets/SPIR.h (+2)
  • (modified) libc/cmake/modules/LLVMLibCArchitectures.cmake (+4)
  • (added) libc/config/gpu/spirv64/config.json (+37)
  • (added) libc/config/gpu/spirv64/entrypoints.txt (+607)
  • (added) libc/config/gpu/spirv64/headers.txt (+21)
  • (added) libc/src/math/spirv64/CMakeLists.txt (+541)
  • (added) libc/src/math/spirv64/acos.cpp (+19)
  • (added) libc/src/math/spirv64/acosf.cpp (+19)
  • (added) libc/src/math/spirv64/acosh.cpp (+19)
  • (added) libc/src/math/spirv64/acoshf.cpp (+19)
  • (added) libc/src/math/spirv64/asin.cpp (+19)
  • (added) libc/src/math/spirv64/asinf.cpp (+19)
  • (added) libc/src/math/spirv64/asinh.cpp (+19)
  • (added) libc/src/math/spirv64/asinhf.cpp (+19)
  • (added) libc/src/math/spirv64/atan.cpp (+19)
  • (added) libc/src/math/spirv64/atan2.cpp (+21)
  • (added) libc/src/math/spirv64/atan2f.cpp (+21)
  • (added) libc/src/math/spirv64/atanf.cpp (+19)
  • (added) libc/src/math/spirv64/atanh.cpp (+19)
  • (added) libc/src/math/spirv64/atanhf.cpp (+19)
  • (added) libc/src/math/spirv64/ceil.cpp (+17)
  • (added) libc/src/math/spirv64/ceilf.cpp (+17)
  • (added) libc/src/math/spirv64/copysign.cpp (+19)
  • (added) libc/src/math/spirv64/copysignf.cpp (+19)
  • (added) libc/src/math/spirv64/cos.cpp (+19)
  • (added) libc/src/math/spirv64/cosf.cpp (+19)
  • (added) libc/src/math/spirv64/cosh.cpp (+19)
  • (added) libc/src/math/spirv64/coshf.cpp (+19)
  • (added) libc/src/math/spirv64/declarations.h (+91)
  • (added) libc/src/math/spirv64/erf.cpp (+19)
  • (added) libc/src/math/spirv64/erff.cpp (+19)
  • (added) libc/src/math/spirv64/exp.cpp (+19)
  • (added) libc/src/math/spirv64/exp10.cpp (+19)
  • (added) libc/src/math/spirv64/exp10f.cpp (+19)
  • (added) libc/src/math/spirv64/exp2.cpp (+19)
  • (added) libc/src/math/spirv64/exp2f.cpp (+19)
  • (added) libc/src/math/spirv64/expf.cpp (+19)
  • (added) libc/src/math/spirv64/expm1.cpp (+19)
  • (added) libc/src/math/spirv64/expm1f.cpp (+19)
  • (added) libc/src/math/spirv64/fabs.cpp (+17)
  • (added) libc/src/math/spirv64/fabsf.cpp (+17)
  • (added) libc/src/math/spirv64/fdim.cpp (+21)
  • (added) libc/src/math/spirv64/fdimf.cpp (+21)
  • (added) libc/src/math/spirv64/floor.cpp (+17)
  • (added) libc/src/math/spirv64/floorf.cpp (+17)
  • (added) libc/src/math/spirv64/fma.cpp (+19)
  • (added) libc/src/math/spirv64/fmaf.cpp (+19)
  • (added) libc/src/math/spirv64/fmax.cpp (+22)
  • (added) libc/src/math/spirv64/fmaxf.cpp (+20)
  • (added) libc/src/math/spirv64/fmin.cpp (+20)
  • (added) libc/src/math/spirv64/fminf.cpp (+20)
  • (added) libc/src/math/spirv64/fmod.cpp (+19)
  • (added) libc/src/math/spirv64/fmodf.cpp (+19)
  • (added) libc/src/math/spirv64/frexp.cpp (+21)
  • (added) libc/src/math/spirv64/frexpf.cpp (+21)
  • (added) libc/src/math/spirv64/hypot.cpp (+21)
  • (added) libc/src/math/spirv64/hypotf.cpp (+21)
  • (added) libc/src/math/spirv64/ilogb.cpp (+19)
  • (added) libc/src/math/spirv64/ilogbf.cpp (+19)
  • (added) libc/src/math/spirv64/ldexp.cpp (+21)
  • (added) libc/src/math/spirv64/ldexpf.cpp (+21)
  • (added) libc/src/math/spirv64/lgamma.cpp (+19)
  • (added) libc/src/math/spirv64/lgamma_r.cpp (+24)
  • (added) libc/src/math/spirv64/llrint.cpp (+21)
  • (added) libc/src/math/spirv64/llrintf.cpp (+21)
  • (added) libc/src/math/spirv64/log.cpp (+19)
  • (added) libc/src/math/spirv64/log10.cpp (+19)
  • (added) libc/src/math/spirv64/log10f.cpp (+19)
  • (added) libc/src/math/spirv64/log1p.cpp (+19)
  • (added) libc/src/math/spirv64/log1pf.cpp (+19)
  • (added) libc/src/math/spirv64/log2.cpp (+19)
  • (added) libc/src/math/spirv64/log2f.cpp (+19)
  • (added) libc/src/math/spirv64/logb.cpp (+19)
  • (added) libc/src/math/spirv64/logbf.cpp (+19)
  • (added) libc/src/math/spirv64/logf.cpp (+19)
  • (added) libc/src/math/spirv64/lrint.cpp (+21)
  • (added) libc/src/math/spirv64/lrintf.cpp (+21)
  • (added) libc/src/math/spirv64/nearbyint.cpp (+19)
  • (added) libc/src/math/spirv64/nearbyintf.cpp (+19)
  • (added) libc/src/math/spirv64/nextafter.cpp (+21)
  • (added) libc/src/math/spirv64/nextafterf.cpp (+21)
  • (added) libc/src/math/spirv64/platform.h (+55)
  • (added) libc/src/math/spirv64/powf.cpp (+21)
  • (added) libc/src/math/spirv64/powi.cpp (+21)
  • (added) libc/src/math/spirv64/powif.cpp (+21)
  • (added) libc/src/math/spirv64/remainder.cpp (+19)
  • (added) libc/src/math/spirv64/remainderf.cpp (+19)
  • (added) libc/src/math/spirv64/remquo.cpp (+24)
  • (added) libc/src/math/spirv64/remquof.cpp (+24)
  • (added) libc/src/math/spirv64/rint.cpp (+17)
  • (added) libc/src/math/spirv64/rintf.cpp (+17)
  • (added) libc/src/math/spirv64/round.cpp (+17)
  • (added) libc/src/math/spirv64/roundf.cpp (+17)
  • (added) libc/src/math/spirv64/scalbn.cpp (+21)
  • (added) libc/src/math/spirv64/scalbnf.cpp (+21)
  • (added) libc/src/math/spirv64/sin.cpp (+19)
  • (added) libc/src/math/spirv64/sincos.cpp (+21)
  • (added) libc/src/math/spirv64/sincosf.cpp (+21)
  • (added) libc/src/math/spirv64/sinf.cpp (+19)
  • (added) libc/src/math/spirv64/sinh.cpp (+19)
  • (added) libc/src/math/spirv64/sinhf.cpp (+19)
  • (added) libc/src/math/spirv64/sqrt.cpp (+17)
  • (added) libc/src/math/spirv64/sqrtf.cpp (+17)
  • (added) libc/src/math/spirv64/tan.cpp (+19)
  • (added) libc/src/math/spirv64/tanf.cpp (+19)
  • (added) libc/src/math/spirv64/tanh.cpp (+19)
  • (added) libc/src/math/spirv64/tanhf.cpp (+19)
  • (added) libc/src/math/spirv64/tgamma.cpp (+19)
  • (added) libc/src/math/spirv64/tgammaf.cpp (+19)
  • (added) libc/src/math/spirv64/trunc.cpp (+17)
  • (added) libc/src/math/spirv64/truncf.cpp (+17)
  • (added) libc/startup/gpu/spirv64/CMakeLists.txt (+15)
  • (added) libc/startup/gpu/spirv64/start.cpp (+80)
  • (modified) lld/ELF/InputFiles.cpp (+5-1)
  • (modified) offload/DeviceRTL/CMakeLists.txt (+5)
  • (modified) offload/DeviceRTL/include/State.h (+18-9)
  • (modified) offload/DeviceRTL/src/State.cpp (+13-8)
  • (modified) offload/cmake/caches/Offload.cmake (+8-6)
  • (modified) offload/test/offloading/bug64959.c (+1-1)
diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h
index 61f9ef7e3e361..610efa1fe00d9 100644
--- a/clang/lib/Basic/Targets/SPIR.h
+++ b/clang/lib/Basic/Targets/SPIR.h
@@ -399,6 +399,8 @@ class LLVM_LIBRARY_VISIBILITY SPIRV64AMDGCNTargetInfo final
     HasLegalHalfType = true;
     HasFloat16 = true;
     HalfArgsAndReturns = true;
+
+    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
   }
 
   bool hasBFloat16Type() const override { return true; }
diff --git a/libc/cmake/modules/LLVMLibCArchitectures.cmake b/libc/cmake/modules/LLVMLibCArchitectures.cmake
index fbb1091ddabab..8d74f71d5cba0 100644
--- a/libc/cmake/modules/LLVMLibCArchitectures.cmake
+++ b/libc/cmake/modules/LLVMLibCArchitectures.cmake
@@ -49,6 +49,8 @@ function(get_arch_and_system_from_triple triple arch_var sys_var)
     set(target_arch "riscv32")
   elseif(target_arch MATCHES "^riscv64")
     set(target_arch "riscv64")
+  elseif(target_arch MATCHES "^spirv64")
+    set(target_arch "spirv64")
   elseif(target_arch MATCHES "^amdgcn")
     set(target_arch "amdgpu")
   elseif(target_arch MATCHES "^nvptx64")
@@ -160,6 +162,8 @@ elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "riscv32")
   set(LIBC_TARGET_ARCHITECTURE "riscv")
 elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "amdgpu")
   set(LIBC_TARGET_ARCHITECTURE_IS_AMDGPU TRUE)
+elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "spirv64")
+  set(LIBC_TARGET_ARCHITECTURE_IS_SPIRV64 TRUE)
 elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "nvptx")
   set(LIBC_TARGET_ARCHITECTURE_IS_NVPTX TRUE)
 else()
diff --git a/libc/config/gpu/spirv64/config.json b/libc/config/gpu/spirv64/config.json
new file mode 100644
index 0000000000000..d99f48ecbede1
--- /dev/null
+++ b/libc/config/gpu/spirv64/config.json
@@ -0,0 +1,37 @@
+{
+  "errno": {
+    "LIBC_CONF_ERRNO_MODE": {
+      "value": "LIBC_ERRNO_MODE_SHARED"
+    }
+  },
+  "printf": {
+    "LIBC_CONF_PRINTF_DISABLE_FLOAT": {
+      "value": true
+    },
+    "LIBC_CONF_PRINTF_DISABLE_INDEX_MODE": {
+      "value": true
+    },
+    "LIBC_CONF_PRINTF_DISABLE_WRITE_INT": {
+      "value": true
+    },
+    "LIBC_CONF_PRINTF_FLOAT_TO_STR_USE_MEGA_LONG_DOUBLE_TABLE": {
+      "value": false
+    },
+    "LIBC_CONF_PRINTF_DISABLE_STRERROR": {
+      "value": true
+    }
+  },
+  "scanf": {
+    "LIBC_CONF_SCANF_DISABLE_FLOAT": {
+      "value": true
+    },
+    "LIBC_CONF_SCANF_DISABLE_INDEX_MODE": {
+      "value": true
+    }
+  },
+  "math": {
+    "LIBC_CONF_MATH_OPTIMIZATIONS": {
+      "value": "(LIBC_MATH_SKIP_ACCURATE_PASS | LIBC_MATH_SMALL_TABLES | LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)"
+    }
+  }
+}
diff --git a/libc/config/gpu/spirv64/entrypoints.txt b/libc/config/gpu/spirv64/entrypoints.txt
new file mode 100644
index 0000000000000..291d86b4dd587
--- /dev/null
+++ b/libc/config/gpu/spirv64/entrypoints.txt
@@ -0,0 +1,607 @@
+set(TARGET_LIBC_ENTRYPOINTS
+    # assert.h entrypoints
+    libc.src.assert.__assert_fail
+
+    # ctype.h entrypoints
+    libc.src.ctype.isalnum
+    libc.src.ctype.isalnum_l
+    libc.src.ctype.isalpha
+    libc.src.ctype.isalpha_l
+    libc.src.ctype.isascii
+    libc.src.ctype.isblank
+    libc.src.ctype.isblank_l
+    libc.src.ctype.iscntrl
+    libc.src.ctype.iscntrl_l
+    libc.src.ctype.isdigit
+    libc.src.ctype.isdigit_l
+    libc.src.ctype.isgraph
+    libc.src.ctype.isgraph_l
+    libc.src.ctype.islower
+    libc.src.ctype.islower_l
+    libc.src.ctype.isprint
+    libc.src.ctype.isprint_l
+    libc.src.ctype.ispunct
+    libc.src.ctype.ispunct_l
+    libc.src.ctype.isspace
+    libc.src.ctype.isspace_l
+    libc.src.ctype.isupper
+    libc.src.ctype.isupper_l
+    libc.src.ctype.isxdigit
+    libc.src.ctype.isxdigit_l
+    libc.src.ctype.toascii
+    libc.src.ctype.tolower
+    libc.src.ctype.tolower_l
+    libc.src.ctype.toupper
+    libc.src.ctype.toupper_l
+
+    # string.h entrypoints
+    libc.src.string.memccpy
+    libc.src.string.memchr
+    libc.src.string.memcmp
+    libc.src.string.memcpy
+    libc.src.string.memmem
+    libc.src.string.memmove
+    libc.src.string.mempcpy
+    libc.src.string.memrchr
+    libc.src.string.memset
+    libc.src.string.stpcpy
+    libc.src.string.stpncpy
+    libc.src.string.strcasestr
+    libc.src.string.strcat
+    libc.src.string.strchr
+    libc.src.string.strchrnul
+    libc.src.string.strcmp
+    libc.src.string.strcoll
+    libc.src.string.strcoll_l
+    libc.src.string.strcpy
+    libc.src.string.strcspn
+    libc.src.string.strdup
+    libc.src.string.strerror
+    libc.src.string.strlcat
+    libc.src.string.strlcpy
+    libc.src.string.strlen
+    libc.src.string.strncat
+    libc.src.string.strncmp
+    libc.src.string.strncpy
+    libc.src.string.strndup
+    libc.src.string.strnlen
+    libc.src.string.strpbrk
+    libc.src.string.strrchr
+    libc.src.string.strsep
+    libc.src.string.strspn
+    libc.src.string.strstr
+    libc.src.string.strtok
+    libc.src.string.strtok_r
+    libc.src.string.strxfrm
+    libc.src.string.strxfrm_l
+
+    # strings.h entrypoints
+    libc.src.strings.bcmp
+    libc.src.strings.bcopy
+    libc.src.strings.bzero
+    libc.src.strings.index
+    libc.src.strings.rindex
+    libc.src.strings.strcasecmp
+    libc.src.strings.strncasecmp
+
+    # stdbit.h entrypoints
+    libc.src.stdbit.stdc_bit_ceil_uc
+    libc.src.stdbit.stdc_bit_ceil_ui
+    libc.src.stdbit.stdc_bit_ceil_ul
+    libc.src.stdbit.stdc_bit_ceil_ull
+    libc.src.stdbit.stdc_bit_ceil_us
+    libc.src.stdbit.stdc_bit_floor_uc
+    libc.src.stdbit.stdc_bit_floor_ui
+    libc.src.stdbit.stdc_bit_floor_ul
+    libc.src.stdbit.stdc_bit_floor_ull
+    libc.src.stdbit.stdc_bit_floor_us
+    libc.src.stdbit.stdc_bit_width_uc
+    libc.src.stdbit.stdc_bit_width_ui
+    libc.src.stdbit.stdc_bit_width_ul
+    libc.src.stdbit.stdc_bit_width_ull
+    libc.src.stdbit.stdc_bit_width_us
+    libc.src.stdbit.stdc_count_ones_uc
+    libc.src.stdbit.stdc_count_ones_ui
+    libc.src.stdbit.stdc_count_ones_ul
+    libc.src.stdbit.stdc_count_ones_ull
+    libc.src.stdbit.stdc_count_ones_us
+    libc.src.stdbit.stdc_count_zeros_uc
+    libc.src.stdbit.stdc_count_zeros_ui
+    libc.src.stdbit.stdc_count_zeros_ul
+    libc.src.stdbit.stdc_count_zeros_ull
+    libc.src.stdbit.stdc_count_zeros_us
+    libc.src.stdbit.stdc_first_leading_one_uc
+    libc.src.stdbit.stdc_first_leading_one_ui
+    libc.src.stdbit.stdc_first_leading_one_ul
+    libc.src.stdbit.stdc_first_leading_one_ull
+    libc.src.stdbit.stdc_first_leading_one_us
+    libc.src.stdbit.stdc_first_leading_zero_uc
+    libc.src.stdbit.stdc_first_leading_zero_ui
+    libc.src.stdbit.stdc_first_leading_zero_ul
+    libc.src.stdbit.stdc_first_leading_zero_ull
+    libc.src.stdbit.stdc_first_leading_zero_us
+    libc.src.stdbit.stdc_first_trailing_one_uc
+    libc.src.stdbit.stdc_first_trailing_one_ui
+    libc.src.stdbit.stdc_first_trailing_one_ul
+    libc.src.stdbit.stdc_first_trailing_one_ull
+    libc.src.stdbit.stdc_first_trailing_one_us
+    libc.src.stdbit.stdc_first_trailing_zero_uc
+    libc.src.stdbit.stdc_first_trailing_zero_ui
+    libc.src.stdbit.stdc_first_trailing_zero_ul
+    libc.src.stdbit.stdc_first_trailing_zero_ull
+    libc.src.stdbit.stdc_first_trailing_zero_us
+    libc.src.stdbit.stdc_has_single_bit_uc
+    libc.src.stdbit.stdc_has_single_bit_ui
+    libc.src.stdbit.stdc_has_single_bit_ul
+    libc.src.stdbit.stdc_has_single_bit_ull
+    libc.src.stdbit.stdc_has_single_bit_us
+    libc.src.stdbit.stdc_leading_ones_uc
+    libc.src.stdbit.stdc_leading_ones_ui
+    libc.src.stdbit.stdc_leading_ones_ul
+    libc.src.stdbit.stdc_leading_ones_ull
+    libc.src.stdbit.stdc_leading_ones_us
+    libc.src.stdbit.stdc_leading_zeros_uc
+    libc.src.stdbit.stdc_leading_zeros_ui
+    libc.src.stdbit.stdc_leading_zeros_ul
+    libc.src.stdbit.stdc_leading_zeros_ull
+    libc.src.stdbit.stdc_leading_zeros_us
+    libc.src.stdbit.stdc_trailing_ones_uc
+    libc.src.stdbit.stdc_trailing_ones_ui
+    libc.src.stdbit.stdc_trailing_ones_ul
+    libc.src.stdbit.stdc_trailing_ones_ull
+    libc.src.stdbit.stdc_trailing_ones_us
+    libc.src.stdbit.stdc_trailing_zeros_uc
+    libc.src.stdbit.stdc_trailing_zeros_ui
+    libc.src.stdbit.stdc_trailing_zeros_ul
+    libc.src.stdbit.stdc_trailing_zeros_ull
+    libc.src.stdbit.stdc_trailing_zeros_us
+
+    # stdlib.h entrypoints
+    libc.src.stdlib._Exit
+    libc.src.stdlib.abort
+    libc.src.stdlib.abs
+    libc.src.stdlib.atexit
+    libc.src.stdlib.atof
+    libc.src.stdlib.atoi
+    libc.src.stdlib.atol
+    libc.src.stdlib.atoll
+    libc.src.stdlib.bsearch
+    libc.src.stdlib.div
+    libc.src.stdlib.exit
+    libc.src.stdlib.labs
+    libc.src.stdlib.ldiv
+    libc.src.stdlib.llabs
+    libc.src.stdlib.lldiv
+    libc.src.stdlib.qsort
+    libc.src.stdlib.qsort_r
+    libc.src.stdlib.rand
+    libc.src.stdlib.srand
+    libc.src.stdlib.strtod
+    libc.src.stdlib.strtod_l
+    libc.src.stdlib.strtof
+    libc.src.stdlib.strtof_l
+    libc.src.stdlib.strtol
+    libc.src.stdlib.strtol_l
+    libc.src.stdlib.strtold
+    libc.src.stdlib.strtold_l
+    libc.src.stdlib.strtoll
+    libc.src.stdlib.strtoll_l
+    libc.src.stdlib.strtoul
+    libc.src.stdlib.strtoul_l
+    libc.src.stdlib.strtoull
+    libc.src.stdlib.strtoull_l
+    libc.src.stdlib.at_quick_exit
+    libc.src.stdlib.quick_exit
+    libc.src.stdlib.getenv
+    libc.src.stdlib.system
+
+    # TODO: Implement these correctly
+    libc.src.stdlib.aligned_alloc
+    libc.src.stdlib.calloc
+    libc.src.stdlib.free
+    libc.src.stdlib.malloc
+    libc.src.stdlib.realloc
+
+    # errno.h entrypoints
+    libc.src.errno.errno
+
+    # stdio.h entrypoints
+    libc.src.stdio.clearerr
+    libc.src.stdio.fclose
+    libc.src.stdio.printf
+    libc.src.stdio.vprintf
+    libc.src.stdio.fprintf
+    libc.src.stdio.vfprintf
+    libc.src.stdio.snprintf
+    libc.src.stdio.sprintf
+    libc.src.stdio.vsnprintf
+    libc.src.stdio.vsprintf
+    libc.src.stdio.asprintf
+    libc.src.stdio.vasprintf
+    libc.src.stdio.scanf
+    libc.src.stdio.vscanf
+    libc.src.stdio.fscanf
+    libc.src.stdio.vfscanf
+    libc.src.stdio.sscanf
+    libc.src.stdio.vsscanf
+    libc.src.stdio.feof
+    libc.src.stdio.ferror
+    libc.src.stdio.fflush
+    libc.src.stdio.fgetc
+    libc.src.stdio.fgets
+    libc.src.stdio.fopen
+    libc.src.stdio.fputc
+    libc.src.stdio.fputs
+    libc.src.stdio.fread
+    libc.src.stdio.fseek
+    libc.src.stdio.ftell
+    libc.src.stdio.fwrite
+    libc.src.stdio.getc
+    libc.src.stdio.getchar
+    libc.src.stdio.putc
+    libc.src.stdio.putchar
+    libc.src.stdio.puts
+    libc.src.stdio.remove
+    libc.src.stdio.rename
+    libc.src.stdio.stderr
+    libc.src.stdio.stdin
+    libc.src.stdio.stdout
+    libc.src.stdio.ungetc
+
+    # inttypes.h entrypoints
+    libc.src.inttypes.imaxabs
+    libc.src.inttypes.imaxdiv
+    libc.src.inttypes.strtoimax
+    libc.src.inttypes.strtoumax
+
+    # time.h entrypoints
+    libc.src.time.clock
+    libc.src.time.clock_gettime
+    libc.src.time.timespec_get
+    libc.src.time.nanosleep
+    libc.src.time.strftime
+    libc.src.time.strftime_l
+
+    # wchar.h entrypoints
+    libc.src.wchar.wcslen
+    libc.src.wchar.wctob
+
+    # locale.h entrypoints
+    libc.src.locale.localeconv
+    libc.src.locale.duplocale
+    libc.src.locale.freelocale
+    libc.src.locale.localeconv
+    libc.src.locale.newlocale
+    libc.src.locale.setlocale
+    libc.src.locale.uselocale
+)
+
+set(TARGET_LIBM_ENTRYPOINTS
+    # math.h entrypoints
+    libc.src.math.acos
+    libc.src.math.acosf
+    libc.src.math.acosh
+    libc.src.math.acoshf
+    libc.src.math.asin
+    libc.src.math.asinf
+    libc.src.math.asinh
+    libc.src.math.asinhf
+    libc.src.math.atan
+    libc.src.math.atan2
+    libc.src.math.atan2f
+    libc.src.math.atan2l
+    libc.src.math.atanf
+    libc.src.math.atanh
+    libc.src.math.atanhf
+    libc.src.math.canonicalize
+    libc.src.math.canonicalizef
+    libc.src.math.canonicalizel
+    libc.src.math.cbrt
+    libc.src.math.cbrtf
+    libc.src.math.ceil
+    libc.src.math.ceilf
+    libc.src.math.ceill
+    libc.src.math.copysign
+    libc.src.math.copysignf
+    libc.src.math.copysignl
+    libc.src.math.cos
+    libc.src.math.cosf
+    libc.src.math.cosh
+    libc.src.math.coshf
+    libc.src.math.cospif
+    libc.src.math.ddivl
+    libc.src.math.dfmal
+    libc.src.math.dmull
+    libc.src.math.dsqrtl
+    libc.src.math.erf
+    libc.src.math.erff
+    libc.src.math.exp
+    libc.src.math.exp10
+    libc.src.math.exp10f
+    libc.src.math.exp2
+    libc.src.math.exp2f
+    libc.src.math.exp2m1f
+    libc.src.math.expf
+    libc.src.math.expm1
+    libc.src.math.expm1f
+    libc.src.math.fabs
+    libc.src.math.fabsf
+    libc.src.math.fabsl
+    libc.src.math.fadd
+    libc.src.math.faddl
+    libc.src.math.fdim
+    libc.src.math.fdimf
+    libc.src.math.fdiml
+    libc.src.math.fdiv
+    libc.src.math.fdivl
+    libc.src.math.ffma
+    libc.src.math.ffmal
+    libc.src.math.floor
+    libc.src.math.floorf
+    libc.src.math.floorl
+    libc.src.math.fma
+    libc.src.math.fmaf
+    libc.src.math.fmax
+    libc.src.math.fmaxf
+    libc.src.math.fmaximum
+    libc.src.math.fmaximumf
+    libc.src.math.fmaximuml
+    libc.src.math.fmaximum_mag
+    libc.src.math.fmaximum_magf
+    libc.src.math.fmaximum_magl
+    libc.src.math.fmaximum_mag_num
+    libc.src.math.fmaximum_mag_numf
+    libc.src.math.fmaximum_mag_numl
+    libc.src.math.fmaximum_num
+    libc.src.math.fmaximum_numf
+    libc.src.math.fmaximum_numl
+    libc.src.math.fmaxl
+    libc.src.math.fmin
+    libc.src.math.fminf
+    libc.src.math.fminimum
+    libc.src.math.fminimumf
+    libc.src.math.fminimuml
+    libc.src.math.fminimum_mag
+    libc.src.math.fminimum_magf
+    libc.src.math.fminimum_magl
+    libc.src.math.fminimum_mag_num
+    libc.src.math.fminimum_mag_numf
+    libc.src.math.fminimum_mag_numl
+    libc.src.math.fminimum_num
+    libc.src.math.fminimum_numf
+    libc.src.math.fminimum_numl
+    libc.src.math.fminl
+    libc.src.math.fmod
+    libc.src.math.fmodf
+    libc.src.math.fmodl
+    libc.src.math.fmul
+    libc.src.math.fmull
+    libc.src.math.frexp
+    libc.src.math.frexpf
+    libc.src.math.frexpl
+    libc.src.math.fromfp
+    libc.src.math.fromfpf
+    libc.src.math.fromfpl
+    libc.src.math.fromfpx
+    libc.src.math.fromfpxf
+    libc.src.math.fromfpxl
+    libc.src.math.fsqrt
+    libc.src.math.fsqrtl
+    libc.src.math.fsub
+    libc.src.math.fsubl
+    libc.src.math.getpayload
+    libc.src.math.getpayloadf
+    libc.src.math.getpayloadl
+    libc.src.math.hypot
+    libc.src.math.hypotf
+    libc.src.math.ilogb
+    libc.src.math.ilogbf
+    libc.src.math.ilogbl
+    libc.src.math.isnan
+    libc.src.math.isnanf
+    libc.src.math.isnanl
+    libc.src.math.ldexp
+    libc.src.math.ldexpf
+    libc.src.math.ldexpl
+    libc.src.math.lgamma
+    libc.src.math.lgamma_r
+    libc.src.math.llogb
+    libc.src.math.llogbf
+    libc.src.math.llogbl
+    libc.src.math.llrint
+    libc.src.math.llrintf
+    libc.src.math.llrintl
+    libc.src.math.llround
+    libc.src.math.llroundf
+    libc.src.math.llroundl
+    libc.src.math.log
+    libc.src.math.log10
+    libc.src.math.log10f
+    libc.src.math.log1p
+    libc.src.math.log1pf
+    libc.src.math.log2
+    libc.src.math.log2f
+    libc.src.math.logb
+    libc.src.math.logbf
+    libc.src.math.logbl
+    libc.src.math.logf
+    libc.src.math.lrint
+    libc.src.math.lrintf
+    libc.src.math.lrintl
+    libc.src.math.lround
+    libc.src.math.lroundf
+    libc.src.math.lroundl
+    libc.src.math.modf
+    libc.src.math.modff
+    libc.src.math.modfl
+    libc.src.math.nan
+    libc.src.math.nanf
+    libc.src.math.nanl
+    libc.src.math.nearbyint
+    libc.src.math.nearbyintf
+    libc.src.math.nearbyintl
+    libc.src.math.nextafter
+    libc.src.math.nextafterf
+    libc.src.math.nextafterl
+    libc.src.math.nextdown
+    libc.src.math.nextdownf
+    libc.src.math.nextdownl
+    libc.src.math.nexttoward
+    libc.src.math.nexttowardf
+    libc.src.math.nexttowardl
+    libc.src.math.nextup
+    libc.src.math.nextupf
+    libc.src.math.nextupl
+    libc.src.math.pow
+    libc.src.math.powf
+    libc.src.math.powi
+    libc.src.math.powif
+    libc.src.math.remainder
+    libc.src.math.remainderf
+    libc.src.math.remainderl
+    libc.src.math.remquo
+    libc.src.math.remquof
+    libc.src.math.remquol
+    libc.src.math.rint
+    libc.src.math.rintf
+    libc.src.math.rintl
+    libc.src.math.roundeven
+    libc.src.math.roundevenf
+    libc.src.math.roundevenl
+    libc.src.math.round
+    libc.src.math.roundf
+    libc.src.math.roundl
+    libc.src.math.scalbln
+    libc.src.math.scalblnf
+    libc.src.math.scalblnl
+    libc.src.math.scalbn
+    libc.src.math.scalbnf
+    libc.src.math.scalbnl
+    libc.src.math.setpayload
+    libc.src.math.setpayloadf
+    libc.src.math.setpayloadl
+    libc.src.math.setpayloadsig
+    libc.src.math.setpayloadsigf
+    libc.src.math.setpayloadsigl
+    libc.src.math.sin
+    libc.src.math.sincos
+    libc.src.math.sincosf
+    libc.src.math.sinf
+    libc.src.math.sinh
+    libc.src.math.sinhf
+    libc.src.math.sinpif
+    libc.src.math.sqrt
+    libc.src.math.sqrtf
+    libc.src.math.sqrtl
+    libc.src.math.tan
+    libc.src.math.tanf
+    libc.src.math.tanh
+    libc.src.math.tanhf
+    libc.src.math.tgamma
+    libc.src.math.tgammaf
+    libc.src.math.totalorder
+    libc.src.math.totalorderf
+    libc.src.math.totalorderl
+    libc.src.math.totalordermag
+    libc.src.math.totalordermagf
+    libc.src.math.totalordermagl
+    libc.src.math.trunc
+    libc.src.math.truncf
+    libc.src.math.truncl
+    libc.src.math.ufromfp
+    libc.src.math.ufromfpf
+    libc.src.math.ufromfpl
+    libc.src.math.ufromfpx
+    libc.src.math.ufromfpxf
+    libc.src.math.ufromfpxl
+)
+
+if(LIBC_TYPES_HAS_FLOAT16)
+  list(APPEND TARGET_LIBM_ENTRYPOINTS
+    # math.h C23 _Float16 entrypoints
+    libc.src.math.canonicalizef16
+    libc.src.math.ceilf16
+    libc.src.math.copysignf16
+    libc.src.math.coshf16
+    libc.src.math.exp10f16
+    libc.src.math.exp10m1f16
+    libc.src.math.exp2f16
+    libc.src.math.expf16
+    libc.src.math.f16add
+    libc.src.math.f16addf
+    libc.src.math.f16addl
+    libc.src.math.f16div
+    libc.src.math.f16divf
+    libc.src.math.f16divl
+    libc.src.math.f16fma
+    libc.src.math.f16fmaf
+    libc.src.math.f16fmal
+    libc.src.math.f16mul
+    libc.src.math.f16mulf
+    libc.src.math.f16mull
+    libc.src.math.f16sqrt
+    libc.src.math.f16sqrtf
+    libc.src.math.f16sqrtl
+    libc.src.math.f16sub
+    libc.src.math.f16subf
+    libc.src.math.f16subl
+    libc.src.math.fabsf16
+    libc.src.math.fdimf16
+    libc.src.math.floorf16
+    libc.src.math.fmaxf16
+    libc.src.math.fmaximum_mag_numf16
+    libc.src.math.fmaximum_magf16
+    libc.src.math.fmaximum_numf16
+    libc.src.math.fmaximumf16
+    libc.src.math.fminf16
+    libc.src.math.fminimum_mag_numf16
+    libc.src.math.fminimum_magf16
+    libc.src.math.fminimum_numf16
+    libc.src.math.fminimumf16
+    libc.src.math.fmodf16
+    libc.src.math.frexpf16
+    libc.src.math.fromfpf16
+    libc.src.math.fromfpxf16
+    libc.src.math.getpayloadf16
+    libc.src.math.ilogbf16
+    libc.src.math.ldexpf16
+    libc.src.math.llogbf16
+    libc.src.math.llrintf16
+    libc.src.math.llroundf16
+    libc.src.math.log10f16
+    libc.src.math.log2f16
+    libc.src.math.logbf16
+    libc.src.math.logf16
+    libc.src.math.lrintf16
+    libc.src.math.lroundf16
+    libc.src.math.modff16
+    libc.src.math.nanf16
+    libc.src.math.nearbyintf16
+    libc.src.math.nextafterf16
+    libc.src.math.nextdownf16
+    libc.src.math.nexttowardf16
+    libc.src.math.nextupf16
+    libc.src.math.remainderf16
+    libc.src.math.remquof16
+    libc.src.math.rintf16
+    libc.src.math.roundevenf16
+    libc.src.math.roundf16
+    libc.src.math.scalblnf16
+    libc.src.math.scalbnf16
+    libc.src.math.setpayloadf16
+    libc.src.math.setpayloadsigf16
+    libc.src.math.sinhf16
+    libc.src.math.sqrtf16
+    libc.src.math.tanhf16
+    libc.src.math.totalorderf16
+    libc.src.math.totalordermagf16
+    libc.src.math.truncf16
+    libc.src.math.ufromfpf16
+    libc.src.math.ufromfpxf16
+  )
+endif()
+
+set(TARGET_LLVMLIBC_ENTRYPOINTS
+  ${TARGET_LIBC_ENTRYPOINTS}
+  ${TARGET_LIBM_ENTRYPOINTS}
+)
diff --git a/libc/config/gpu/spirv64/headers.txt b/libc/config/gpu/s...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Feb 24, 2025

@llvm/pr-subscribers-libc

Author: Jon Chesterfield (JonChesterfield)

Changes

Hopefully we can do better before landing. Posting for discussion.

Didn't learn a huge amount. spirv rejects the clang::amdgpu_kernel annotation and I can't work out how that's supposed to be spelled.

Libc doesn't do anything with address spaces which upsets spirv (unlike openmp which does lots)

The libc build streams bitcode through lld which refuses to do anything with it, but that can be patched.

Port is mostly copying the amdgpu folders to spirv64. Not happy with cmake assuming that spirv64 means amdgpu but also don't understand how to stop it making that assumption.

Lots of libm seems to be dead. I'm hoping Joseph will delete said dead code as it makes this patch look excessively large.

Also doesn't seem ideal to have copy&pasted the config entrypoints stuff.

Don't have a loader, probably reasonable to write one that calls llvm to jit spirv though.


Patch is 136.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/128585.diff

119 Files Affected:

  • (modified) clang/lib/Basic/Targets/SPIR.h (+2)
  • (modified) libc/cmake/modules/LLVMLibCArchitectures.cmake (+4)
  • (added) libc/config/gpu/spirv64/config.json (+37)
  • (added) libc/config/gpu/spirv64/entrypoints.txt (+607)
  • (added) libc/config/gpu/spirv64/headers.txt (+21)
  • (added) libc/src/math/spirv64/CMakeLists.txt (+541)
  • (added) libc/src/math/spirv64/acos.cpp (+19)
  • (added) libc/src/math/spirv64/acosf.cpp (+19)
  • (added) libc/src/math/spirv64/acosh.cpp (+19)
  • (added) libc/src/math/spirv64/acoshf.cpp (+19)
  • (added) libc/src/math/spirv64/asin.cpp (+19)
  • (added) libc/src/math/spirv64/asinf.cpp (+19)
  • (added) libc/src/math/spirv64/asinh.cpp (+19)
  • (added) libc/src/math/spirv64/asinhf.cpp (+19)
  • (added) libc/src/math/spirv64/atan.cpp (+19)
  • (added) libc/src/math/spirv64/atan2.cpp (+21)
  • (added) libc/src/math/spirv64/atan2f.cpp (+21)
  • (added) libc/src/math/spirv64/atanf.cpp (+19)
  • (added) libc/src/math/spirv64/atanh.cpp (+19)
  • (added) libc/src/math/spirv64/atanhf.cpp (+19)
  • (added) libc/src/math/spirv64/ceil.cpp (+17)
  • (added) libc/src/math/spirv64/ceilf.cpp (+17)
  • (added) libc/src/math/spirv64/copysign.cpp (+19)
  • (added) libc/src/math/spirv64/copysignf.cpp (+19)
  • (added) libc/src/math/spirv64/cos.cpp (+19)
  • (added) libc/src/math/spirv64/cosf.cpp (+19)
  • (added) libc/src/math/spirv64/cosh.cpp (+19)
  • (added) libc/src/math/spirv64/coshf.cpp (+19)
  • (added) libc/src/math/spirv64/declarations.h (+91)
  • (added) libc/src/math/spirv64/erf.cpp (+19)
  • (added) libc/src/math/spirv64/erff.cpp (+19)
  • (added) libc/src/math/spirv64/exp.cpp (+19)
  • (added) libc/src/math/spirv64/exp10.cpp (+19)
  • (added) libc/src/math/spirv64/exp10f.cpp (+19)
  • (added) libc/src/math/spirv64/exp2.cpp (+19)
  • (added) libc/src/math/spirv64/exp2f.cpp (+19)
  • (added) libc/src/math/spirv64/expf.cpp (+19)
  • (added) libc/src/math/spirv64/expm1.cpp (+19)
  • (added) libc/src/math/spirv64/expm1f.cpp (+19)
  • (added) libc/src/math/spirv64/fabs.cpp (+17)
  • (added) libc/src/math/spirv64/fabsf.cpp (+17)
  • (added) libc/src/math/spirv64/fdim.cpp (+21)
  • (added) libc/src/math/spirv64/fdimf.cpp (+21)
  • (added) libc/src/math/spirv64/floor.cpp (+17)
  • (added) libc/src/math/spirv64/floorf.cpp (+17)
  • (added) libc/src/math/spirv64/fma.cpp (+19)
  • (added) libc/src/math/spirv64/fmaf.cpp (+19)
  • (added) libc/src/math/spirv64/fmax.cpp (+22)
  • (added) libc/src/math/spirv64/fmaxf.cpp (+20)
  • (added) libc/src/math/spirv64/fmin.cpp (+20)
  • (added) libc/src/math/spirv64/fminf.cpp (+20)
  • (added) libc/src/math/spirv64/fmod.cpp (+19)
  • (added) libc/src/math/spirv64/fmodf.cpp (+19)
  • (added) libc/src/math/spirv64/frexp.cpp (+21)
  • (added) libc/src/math/spirv64/frexpf.cpp (+21)
  • (added) libc/src/math/spirv64/hypot.cpp (+21)
  • (added) libc/src/math/spirv64/hypotf.cpp (+21)
  • (added) libc/src/math/spirv64/ilogb.cpp (+19)
  • (added) libc/src/math/spirv64/ilogbf.cpp (+19)
  • (added) libc/src/math/spirv64/ldexp.cpp (+21)
  • (added) libc/src/math/spirv64/ldexpf.cpp (+21)
  • (added) libc/src/math/spirv64/lgamma.cpp (+19)
  • (added) libc/src/math/spirv64/lgamma_r.cpp (+24)
  • (added) libc/src/math/spirv64/llrint.cpp (+21)
  • (added) libc/src/math/spirv64/llrintf.cpp (+21)
  • (added) libc/src/math/spirv64/log.cpp (+19)
  • (added) libc/src/math/spirv64/log10.cpp (+19)
  • (added) libc/src/math/spirv64/log10f.cpp (+19)
  • (added) libc/src/math/spirv64/log1p.cpp (+19)
  • (added) libc/src/math/spirv64/log1pf.cpp (+19)
  • (added) libc/src/math/spirv64/log2.cpp (+19)
  • (added) libc/src/math/spirv64/log2f.cpp (+19)
  • (added) libc/src/math/spirv64/logb.cpp (+19)
  • (added) libc/src/math/spirv64/logbf.cpp (+19)
  • (added) libc/src/math/spirv64/logf.cpp (+19)
  • (added) libc/src/math/spirv64/lrint.cpp (+21)
  • (added) libc/src/math/spirv64/lrintf.cpp (+21)
  • (added) libc/src/math/spirv64/nearbyint.cpp (+19)
  • (added) libc/src/math/spirv64/nearbyintf.cpp (+19)
  • (added) libc/src/math/spirv64/nextafter.cpp (+21)
  • (added) libc/src/math/spirv64/nextafterf.cpp (+21)
  • (added) libc/src/math/spirv64/platform.h (+55)
  • (added) libc/src/math/spirv64/powf.cpp (+21)
  • (added) libc/src/math/spirv64/powi.cpp (+21)
  • (added) libc/src/math/spirv64/powif.cpp (+21)
  • (added) libc/src/math/spirv64/remainder.cpp (+19)
  • (added) libc/src/math/spirv64/remainderf.cpp (+19)
  • (added) libc/src/math/spirv64/remquo.cpp (+24)
  • (added) libc/src/math/spirv64/remquof.cpp (+24)
  • (added) libc/src/math/spirv64/rint.cpp (+17)
  • (added) libc/src/math/spirv64/rintf.cpp (+17)
  • (added) libc/src/math/spirv64/round.cpp (+17)
  • (added) libc/src/math/spirv64/roundf.cpp (+17)
  • (added) libc/src/math/spirv64/scalbn.cpp (+21)
  • (added) libc/src/math/spirv64/scalbnf.cpp (+21)
  • (added) libc/src/math/spirv64/sin.cpp (+19)
  • (added) libc/src/math/spirv64/sincos.cpp (+21)
  • (added) libc/src/math/spirv64/sincosf.cpp (+21)
  • (added) libc/src/math/spirv64/sinf.cpp (+19)
  • (added) libc/src/math/spirv64/sinh.cpp (+19)
  • (added) libc/src/math/spirv64/sinhf.cpp (+19)
  • (added) libc/src/math/spirv64/sqrt.cpp (+17)
  • (added) libc/src/math/spirv64/sqrtf.cpp (+17)
  • (added) libc/src/math/spirv64/tan.cpp (+19)
  • (added) libc/src/math/spirv64/tanf.cpp (+19)
  • (added) libc/src/math/spirv64/tanh.cpp (+19)
  • (added) libc/src/math/spirv64/tanhf.cpp (+19)
  • (added) libc/src/math/spirv64/tgamma.cpp (+19)
  • (added) libc/src/math/spirv64/tgammaf.cpp (+19)
  • (added) libc/src/math/spirv64/trunc.cpp (+17)
  • (added) libc/src/math/spirv64/truncf.cpp (+17)
  • (added) libc/startup/gpu/spirv64/CMakeLists.txt (+15)
  • (added) libc/startup/gpu/spirv64/start.cpp (+80)
  • (modified) lld/ELF/InputFiles.cpp (+5-1)
  • (modified) offload/DeviceRTL/CMakeLists.txt (+5)
  • (modified) offload/DeviceRTL/include/State.h (+18-9)
  • (modified) offload/DeviceRTL/src/State.cpp (+13-8)
  • (modified) offload/cmake/caches/Offload.cmake (+8-6)
  • (modified) offload/test/offloading/bug64959.c (+1-1)
diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h
index 61f9ef7e3e361..610efa1fe00d9 100644
--- a/clang/lib/Basic/Targets/SPIR.h
+++ b/clang/lib/Basic/Targets/SPIR.h
@@ -399,6 +399,8 @@ class LLVM_LIBRARY_VISIBILITY SPIRV64AMDGCNTargetInfo final
     HasLegalHalfType = true;
     HasFloat16 = true;
     HalfArgsAndReturns = true;
+
+    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
   }
 
   bool hasBFloat16Type() const override { return true; }
diff --git a/libc/cmake/modules/LLVMLibCArchitectures.cmake b/libc/cmake/modules/LLVMLibCArchitectures.cmake
index fbb1091ddabab..8d74f71d5cba0 100644
--- a/libc/cmake/modules/LLVMLibCArchitectures.cmake
+++ b/libc/cmake/modules/LLVMLibCArchitectures.cmake
@@ -49,6 +49,8 @@ function(get_arch_and_system_from_triple triple arch_var sys_var)
     set(target_arch "riscv32")
   elseif(target_arch MATCHES "^riscv64")
     set(target_arch "riscv64")
+  elseif(target_arch MATCHES "^spirv64")
+    set(target_arch "spirv64")
   elseif(target_arch MATCHES "^amdgcn")
     set(target_arch "amdgpu")
   elseif(target_arch MATCHES "^nvptx64")
@@ -160,6 +162,8 @@ elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "riscv32")
   set(LIBC_TARGET_ARCHITECTURE "riscv")
 elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "amdgpu")
   set(LIBC_TARGET_ARCHITECTURE_IS_AMDGPU TRUE)
+elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "spirv64")
+  set(LIBC_TARGET_ARCHITECTURE_IS_SPIRV64 TRUE)
 elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "nvptx")
   set(LIBC_TARGET_ARCHITECTURE_IS_NVPTX TRUE)
 else()
diff --git a/libc/config/gpu/spirv64/config.json b/libc/config/gpu/spirv64/config.json
new file mode 100644
index 0000000000000..d99f48ecbede1
--- /dev/null
+++ b/libc/config/gpu/spirv64/config.json
@@ -0,0 +1,37 @@
+{
+  "errno": {
+    "LIBC_CONF_ERRNO_MODE": {
+      "value": "LIBC_ERRNO_MODE_SHARED"
+    }
+  },
+  "printf": {
+    "LIBC_CONF_PRINTF_DISABLE_FLOAT": {
+      "value": true
+    },
+    "LIBC_CONF_PRINTF_DISABLE_INDEX_MODE": {
+      "value": true
+    },
+    "LIBC_CONF_PRINTF_DISABLE_WRITE_INT": {
+      "value": true
+    },
+    "LIBC_CONF_PRINTF_FLOAT_TO_STR_USE_MEGA_LONG_DOUBLE_TABLE": {
+      "value": false
+    },
+    "LIBC_CONF_PRINTF_DISABLE_STRERROR": {
+      "value": true
+    }
+  },
+  "scanf": {
+    "LIBC_CONF_SCANF_DISABLE_FLOAT": {
+      "value": true
+    },
+    "LIBC_CONF_SCANF_DISABLE_INDEX_MODE": {
+      "value": true
+    }
+  },
+  "math": {
+    "LIBC_CONF_MATH_OPTIMIZATIONS": {
+      "value": "(LIBC_MATH_SKIP_ACCURATE_PASS | LIBC_MATH_SMALL_TABLES | LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)"
+    }
+  }
+}
diff --git a/libc/config/gpu/spirv64/entrypoints.txt b/libc/config/gpu/spirv64/entrypoints.txt
new file mode 100644
index 0000000000000..291d86b4dd587
--- /dev/null
+++ b/libc/config/gpu/spirv64/entrypoints.txt
@@ -0,0 +1,607 @@
+set(TARGET_LIBC_ENTRYPOINTS
+    # assert.h entrypoints
+    libc.src.assert.__assert_fail
+
+    # ctype.h entrypoints
+    libc.src.ctype.isalnum
+    libc.src.ctype.isalnum_l
+    libc.src.ctype.isalpha
+    libc.src.ctype.isalpha_l
+    libc.src.ctype.isascii
+    libc.src.ctype.isblank
+    libc.src.ctype.isblank_l
+    libc.src.ctype.iscntrl
+    libc.src.ctype.iscntrl_l
+    libc.src.ctype.isdigit
+    libc.src.ctype.isdigit_l
+    libc.src.ctype.isgraph
+    libc.src.ctype.isgraph_l
+    libc.src.ctype.islower
+    libc.src.ctype.islower_l
+    libc.src.ctype.isprint
+    libc.src.ctype.isprint_l
+    libc.src.ctype.ispunct
+    libc.src.ctype.ispunct_l
+    libc.src.ctype.isspace
+    libc.src.ctype.isspace_l
+    libc.src.ctype.isupper
+    libc.src.ctype.isupper_l
+    libc.src.ctype.isxdigit
+    libc.src.ctype.isxdigit_l
+    libc.src.ctype.toascii
+    libc.src.ctype.tolower
+    libc.src.ctype.tolower_l
+    libc.src.ctype.toupper
+    libc.src.ctype.toupper_l
+
+    # string.h entrypoints
+    libc.src.string.memccpy
+    libc.src.string.memchr
+    libc.src.string.memcmp
+    libc.src.string.memcpy
+    libc.src.string.memmem
+    libc.src.string.memmove
+    libc.src.string.mempcpy
+    libc.src.string.memrchr
+    libc.src.string.memset
+    libc.src.string.stpcpy
+    libc.src.string.stpncpy
+    libc.src.string.strcasestr
+    libc.src.string.strcat
+    libc.src.string.strchr
+    libc.src.string.strchrnul
+    libc.src.string.strcmp
+    libc.src.string.strcoll
+    libc.src.string.strcoll_l
+    libc.src.string.strcpy
+    libc.src.string.strcspn
+    libc.src.string.strdup
+    libc.src.string.strerror
+    libc.src.string.strlcat
+    libc.src.string.strlcpy
+    libc.src.string.strlen
+    libc.src.string.strncat
+    libc.src.string.strncmp
+    libc.src.string.strncpy
+    libc.src.string.strndup
+    libc.src.string.strnlen
+    libc.src.string.strpbrk
+    libc.src.string.strrchr
+    libc.src.string.strsep
+    libc.src.string.strspn
+    libc.src.string.strstr
+    libc.src.string.strtok
+    libc.src.string.strtok_r
+    libc.src.string.strxfrm
+    libc.src.string.strxfrm_l
+
+    # strings.h entrypoints
+    libc.src.strings.bcmp
+    libc.src.strings.bcopy
+    libc.src.strings.bzero
+    libc.src.strings.index
+    libc.src.strings.rindex
+    libc.src.strings.strcasecmp
+    libc.src.strings.strncasecmp
+
+    # stdbit.h entrypoints
+    libc.src.stdbit.stdc_bit_ceil_uc
+    libc.src.stdbit.stdc_bit_ceil_ui
+    libc.src.stdbit.stdc_bit_ceil_ul
+    libc.src.stdbit.stdc_bit_ceil_ull
+    libc.src.stdbit.stdc_bit_ceil_us
+    libc.src.stdbit.stdc_bit_floor_uc
+    libc.src.stdbit.stdc_bit_floor_ui
+    libc.src.stdbit.stdc_bit_floor_ul
+    libc.src.stdbit.stdc_bit_floor_ull
+    libc.src.stdbit.stdc_bit_floor_us
+    libc.src.stdbit.stdc_bit_width_uc
+    libc.src.stdbit.stdc_bit_width_ui
+    libc.src.stdbit.stdc_bit_width_ul
+    libc.src.stdbit.stdc_bit_width_ull
+    libc.src.stdbit.stdc_bit_width_us
+    libc.src.stdbit.stdc_count_ones_uc
+    libc.src.stdbit.stdc_count_ones_ui
+    libc.src.stdbit.stdc_count_ones_ul
+    libc.src.stdbit.stdc_count_ones_ull
+    libc.src.stdbit.stdc_count_ones_us
+    libc.src.stdbit.stdc_count_zeros_uc
+    libc.src.stdbit.stdc_count_zeros_ui
+    libc.src.stdbit.stdc_count_zeros_ul
+    libc.src.stdbit.stdc_count_zeros_ull
+    libc.src.stdbit.stdc_count_zeros_us
+    libc.src.stdbit.stdc_first_leading_one_uc
+    libc.src.stdbit.stdc_first_leading_one_ui
+    libc.src.stdbit.stdc_first_leading_one_ul
+    libc.src.stdbit.stdc_first_leading_one_ull
+    libc.src.stdbit.stdc_first_leading_one_us
+    libc.src.stdbit.stdc_first_leading_zero_uc
+    libc.src.stdbit.stdc_first_leading_zero_ui
+    libc.src.stdbit.stdc_first_leading_zero_ul
+    libc.src.stdbit.stdc_first_leading_zero_ull
+    libc.src.stdbit.stdc_first_leading_zero_us
+    libc.src.stdbit.stdc_first_trailing_one_uc
+    libc.src.stdbit.stdc_first_trailing_one_ui
+    libc.src.stdbit.stdc_first_trailing_one_ul
+    libc.src.stdbit.stdc_first_trailing_one_ull
+    libc.src.stdbit.stdc_first_trailing_one_us
+    libc.src.stdbit.stdc_first_trailing_zero_uc
+    libc.src.stdbit.stdc_first_trailing_zero_ui
+    libc.src.stdbit.stdc_first_trailing_zero_ul
+    libc.src.stdbit.stdc_first_trailing_zero_ull
+    libc.src.stdbit.stdc_first_trailing_zero_us
+    libc.src.stdbit.stdc_has_single_bit_uc
+    libc.src.stdbit.stdc_has_single_bit_ui
+    libc.src.stdbit.stdc_has_single_bit_ul
+    libc.src.stdbit.stdc_has_single_bit_ull
+    libc.src.stdbit.stdc_has_single_bit_us
+    libc.src.stdbit.stdc_leading_ones_uc
+    libc.src.stdbit.stdc_leading_ones_ui
+    libc.src.stdbit.stdc_leading_ones_ul
+    libc.src.stdbit.stdc_leading_ones_ull
+    libc.src.stdbit.stdc_leading_ones_us
+    libc.src.stdbit.stdc_leading_zeros_uc
+    libc.src.stdbit.stdc_leading_zeros_ui
+    libc.src.stdbit.stdc_leading_zeros_ul
+    libc.src.stdbit.stdc_leading_zeros_ull
+    libc.src.stdbit.stdc_leading_zeros_us
+    libc.src.stdbit.stdc_trailing_ones_uc
+    libc.src.stdbit.stdc_trailing_ones_ui
+    libc.src.stdbit.stdc_trailing_ones_ul
+    libc.src.stdbit.stdc_trailing_ones_ull
+    libc.src.stdbit.stdc_trailing_ones_us
+    libc.src.stdbit.stdc_trailing_zeros_uc
+    libc.src.stdbit.stdc_trailing_zeros_ui
+    libc.src.stdbit.stdc_trailing_zeros_ul
+    libc.src.stdbit.stdc_trailing_zeros_ull
+    libc.src.stdbit.stdc_trailing_zeros_us
+
+    # stdlib.h entrypoints
+    libc.src.stdlib._Exit
+    libc.src.stdlib.abort
+    libc.src.stdlib.abs
+    libc.src.stdlib.atexit
+    libc.src.stdlib.atof
+    libc.src.stdlib.atoi
+    libc.src.stdlib.atol
+    libc.src.stdlib.atoll
+    libc.src.stdlib.bsearch
+    libc.src.stdlib.div
+    libc.src.stdlib.exit
+    libc.src.stdlib.labs
+    libc.src.stdlib.ldiv
+    libc.src.stdlib.llabs
+    libc.src.stdlib.lldiv
+    libc.src.stdlib.qsort
+    libc.src.stdlib.qsort_r
+    libc.src.stdlib.rand
+    libc.src.stdlib.srand
+    libc.src.stdlib.strtod
+    libc.src.stdlib.strtod_l
+    libc.src.stdlib.strtof
+    libc.src.stdlib.strtof_l
+    libc.src.stdlib.strtol
+    libc.src.stdlib.strtol_l
+    libc.src.stdlib.strtold
+    libc.src.stdlib.strtold_l
+    libc.src.stdlib.strtoll
+    libc.src.stdlib.strtoll_l
+    libc.src.stdlib.strtoul
+    libc.src.stdlib.strtoul_l
+    libc.src.stdlib.strtoull
+    libc.src.stdlib.strtoull_l
+    libc.src.stdlib.at_quick_exit
+    libc.src.stdlib.quick_exit
+    libc.src.stdlib.getenv
+    libc.src.stdlib.system
+
+    # TODO: Implement these correctly
+    libc.src.stdlib.aligned_alloc
+    libc.src.stdlib.calloc
+    libc.src.stdlib.free
+    libc.src.stdlib.malloc
+    libc.src.stdlib.realloc
+
+    # errno.h entrypoints
+    libc.src.errno.errno
+
+    # stdio.h entrypoints
+    libc.src.stdio.clearerr
+    libc.src.stdio.fclose
+    libc.src.stdio.printf
+    libc.src.stdio.vprintf
+    libc.src.stdio.fprintf
+    libc.src.stdio.vfprintf
+    libc.src.stdio.snprintf
+    libc.src.stdio.sprintf
+    libc.src.stdio.vsnprintf
+    libc.src.stdio.vsprintf
+    libc.src.stdio.asprintf
+    libc.src.stdio.vasprintf
+    libc.src.stdio.scanf
+    libc.src.stdio.vscanf
+    libc.src.stdio.fscanf
+    libc.src.stdio.vfscanf
+    libc.src.stdio.sscanf
+    libc.src.stdio.vsscanf
+    libc.src.stdio.feof
+    libc.src.stdio.ferror
+    libc.src.stdio.fflush
+    libc.src.stdio.fgetc
+    libc.src.stdio.fgets
+    libc.src.stdio.fopen
+    libc.src.stdio.fputc
+    libc.src.stdio.fputs
+    libc.src.stdio.fread
+    libc.src.stdio.fseek
+    libc.src.stdio.ftell
+    libc.src.stdio.fwrite
+    libc.src.stdio.getc
+    libc.src.stdio.getchar
+    libc.src.stdio.putc
+    libc.src.stdio.putchar
+    libc.src.stdio.puts
+    libc.src.stdio.remove
+    libc.src.stdio.rename
+    libc.src.stdio.stderr
+    libc.src.stdio.stdin
+    libc.src.stdio.stdout
+    libc.src.stdio.ungetc
+
+    # inttypes.h entrypoints
+    libc.src.inttypes.imaxabs
+    libc.src.inttypes.imaxdiv
+    libc.src.inttypes.strtoimax
+    libc.src.inttypes.strtoumax
+
+    # time.h entrypoints
+    libc.src.time.clock
+    libc.src.time.clock_gettime
+    libc.src.time.timespec_get
+    libc.src.time.nanosleep
+    libc.src.time.strftime
+    libc.src.time.strftime_l
+
+    # wchar.h entrypoints
+    libc.src.wchar.wcslen
+    libc.src.wchar.wctob
+
+    # locale.h entrypoints
+    libc.src.locale.localeconv
+    libc.src.locale.duplocale
+    libc.src.locale.freelocale
+    libc.src.locale.localeconv
+    libc.src.locale.newlocale
+    libc.src.locale.setlocale
+    libc.src.locale.uselocale
+)
+
+set(TARGET_LIBM_ENTRYPOINTS
+    # math.h entrypoints
+    libc.src.math.acos
+    libc.src.math.acosf
+    libc.src.math.acosh
+    libc.src.math.acoshf
+    libc.src.math.asin
+    libc.src.math.asinf
+    libc.src.math.asinh
+    libc.src.math.asinhf
+    libc.src.math.atan
+    libc.src.math.atan2
+    libc.src.math.atan2f
+    libc.src.math.atan2l
+    libc.src.math.atanf
+    libc.src.math.atanh
+    libc.src.math.atanhf
+    libc.src.math.canonicalize
+    libc.src.math.canonicalizef
+    libc.src.math.canonicalizel
+    libc.src.math.cbrt
+    libc.src.math.cbrtf
+    libc.src.math.ceil
+    libc.src.math.ceilf
+    libc.src.math.ceill
+    libc.src.math.copysign
+    libc.src.math.copysignf
+    libc.src.math.copysignl
+    libc.src.math.cos
+    libc.src.math.cosf
+    libc.src.math.cosh
+    libc.src.math.coshf
+    libc.src.math.cospif
+    libc.src.math.ddivl
+    libc.src.math.dfmal
+    libc.src.math.dmull
+    libc.src.math.dsqrtl
+    libc.src.math.erf
+    libc.src.math.erff
+    libc.src.math.exp
+    libc.src.math.exp10
+    libc.src.math.exp10f
+    libc.src.math.exp2
+    libc.src.math.exp2f
+    libc.src.math.exp2m1f
+    libc.src.math.expf
+    libc.src.math.expm1
+    libc.src.math.expm1f
+    libc.src.math.fabs
+    libc.src.math.fabsf
+    libc.src.math.fabsl
+    libc.src.math.fadd
+    libc.src.math.faddl
+    libc.src.math.fdim
+    libc.src.math.fdimf
+    libc.src.math.fdiml
+    libc.src.math.fdiv
+    libc.src.math.fdivl
+    libc.src.math.ffma
+    libc.src.math.ffmal
+    libc.src.math.floor
+    libc.src.math.floorf
+    libc.src.math.floorl
+    libc.src.math.fma
+    libc.src.math.fmaf
+    libc.src.math.fmax
+    libc.src.math.fmaxf
+    libc.src.math.fmaximum
+    libc.src.math.fmaximumf
+    libc.src.math.fmaximuml
+    libc.src.math.fmaximum_mag
+    libc.src.math.fmaximum_magf
+    libc.src.math.fmaximum_magl
+    libc.src.math.fmaximum_mag_num
+    libc.src.math.fmaximum_mag_numf
+    libc.src.math.fmaximum_mag_numl
+    libc.src.math.fmaximum_num
+    libc.src.math.fmaximum_numf
+    libc.src.math.fmaximum_numl
+    libc.src.math.fmaxl
+    libc.src.math.fmin
+    libc.src.math.fminf
+    libc.src.math.fminimum
+    libc.src.math.fminimumf
+    libc.src.math.fminimuml
+    libc.src.math.fminimum_mag
+    libc.src.math.fminimum_magf
+    libc.src.math.fminimum_magl
+    libc.src.math.fminimum_mag_num
+    libc.src.math.fminimum_mag_numf
+    libc.src.math.fminimum_mag_numl
+    libc.src.math.fminimum_num
+    libc.src.math.fminimum_numf
+    libc.src.math.fminimum_numl
+    libc.src.math.fminl
+    libc.src.math.fmod
+    libc.src.math.fmodf
+    libc.src.math.fmodl
+    libc.src.math.fmul
+    libc.src.math.fmull
+    libc.src.math.frexp
+    libc.src.math.frexpf
+    libc.src.math.frexpl
+    libc.src.math.fromfp
+    libc.src.math.fromfpf
+    libc.src.math.fromfpl
+    libc.src.math.fromfpx
+    libc.src.math.fromfpxf
+    libc.src.math.fromfpxl
+    libc.src.math.fsqrt
+    libc.src.math.fsqrtl
+    libc.src.math.fsub
+    libc.src.math.fsubl
+    libc.src.math.getpayload
+    libc.src.math.getpayloadf
+    libc.src.math.getpayloadl
+    libc.src.math.hypot
+    libc.src.math.hypotf
+    libc.src.math.ilogb
+    libc.src.math.ilogbf
+    libc.src.math.ilogbl
+    libc.src.math.isnan
+    libc.src.math.isnanf
+    libc.src.math.isnanl
+    libc.src.math.ldexp
+    libc.src.math.ldexpf
+    libc.src.math.ldexpl
+    libc.src.math.lgamma
+    libc.src.math.lgamma_r
+    libc.src.math.llogb
+    libc.src.math.llogbf
+    libc.src.math.llogbl
+    libc.src.math.llrint
+    libc.src.math.llrintf
+    libc.src.math.llrintl
+    libc.src.math.llround
+    libc.src.math.llroundf
+    libc.src.math.llroundl
+    libc.src.math.log
+    libc.src.math.log10
+    libc.src.math.log10f
+    libc.src.math.log1p
+    libc.src.math.log1pf
+    libc.src.math.log2
+    libc.src.math.log2f
+    libc.src.math.logb
+    libc.src.math.logbf
+    libc.src.math.logbl
+    libc.src.math.logf
+    libc.src.math.lrint
+    libc.src.math.lrintf
+    libc.src.math.lrintl
+    libc.src.math.lround
+    libc.src.math.lroundf
+    libc.src.math.lroundl
+    libc.src.math.modf
+    libc.src.math.modff
+    libc.src.math.modfl
+    libc.src.math.nan
+    libc.src.math.nanf
+    libc.src.math.nanl
+    libc.src.math.nearbyint
+    libc.src.math.nearbyintf
+    libc.src.math.nearbyintl
+    libc.src.math.nextafter
+    libc.src.math.nextafterf
+    libc.src.math.nextafterl
+    libc.src.math.nextdown
+    libc.src.math.nextdownf
+    libc.src.math.nextdownl
+    libc.src.math.nexttoward
+    libc.src.math.nexttowardf
+    libc.src.math.nexttowardl
+    libc.src.math.nextup
+    libc.src.math.nextupf
+    libc.src.math.nextupl
+    libc.src.math.pow
+    libc.src.math.powf
+    libc.src.math.powi
+    libc.src.math.powif
+    libc.src.math.remainder
+    libc.src.math.remainderf
+    libc.src.math.remainderl
+    libc.src.math.remquo
+    libc.src.math.remquof
+    libc.src.math.remquol
+    libc.src.math.rint
+    libc.src.math.rintf
+    libc.src.math.rintl
+    libc.src.math.roundeven
+    libc.src.math.roundevenf
+    libc.src.math.roundevenl
+    libc.src.math.round
+    libc.src.math.roundf
+    libc.src.math.roundl
+    libc.src.math.scalbln
+    libc.src.math.scalblnf
+    libc.src.math.scalblnl
+    libc.src.math.scalbn
+    libc.src.math.scalbnf
+    libc.src.math.scalbnl
+    libc.src.math.setpayload
+    libc.src.math.setpayloadf
+    libc.src.math.setpayloadl
+    libc.src.math.setpayloadsig
+    libc.src.math.setpayloadsigf
+    libc.src.math.setpayloadsigl
+    libc.src.math.sin
+    libc.src.math.sincos
+    libc.src.math.sincosf
+    libc.src.math.sinf
+    libc.src.math.sinh
+    libc.src.math.sinhf
+    libc.src.math.sinpif
+    libc.src.math.sqrt
+    libc.src.math.sqrtf
+    libc.src.math.sqrtl
+    libc.src.math.tan
+    libc.src.math.tanf
+    libc.src.math.tanh
+    libc.src.math.tanhf
+    libc.src.math.tgamma
+    libc.src.math.tgammaf
+    libc.src.math.totalorder
+    libc.src.math.totalorderf
+    libc.src.math.totalorderl
+    libc.src.math.totalordermag
+    libc.src.math.totalordermagf
+    libc.src.math.totalordermagl
+    libc.src.math.trunc
+    libc.src.math.truncf
+    libc.src.math.truncl
+    libc.src.math.ufromfp
+    libc.src.math.ufromfpf
+    libc.src.math.ufromfpl
+    libc.src.math.ufromfpx
+    libc.src.math.ufromfpxf
+    libc.src.math.ufromfpxl
+)
+
+if(LIBC_TYPES_HAS_FLOAT16)
+  list(APPEND TARGET_LIBM_ENTRYPOINTS
+    # math.h C23 _Float16 entrypoints
+    libc.src.math.canonicalizef16
+    libc.src.math.ceilf16
+    libc.src.math.copysignf16
+    libc.src.math.coshf16
+    libc.src.math.exp10f16
+    libc.src.math.exp10m1f16
+    libc.src.math.exp2f16
+    libc.src.math.expf16
+    libc.src.math.f16add
+    libc.src.math.f16addf
+    libc.src.math.f16addl
+    libc.src.math.f16div
+    libc.src.math.f16divf
+    libc.src.math.f16divl
+    libc.src.math.f16fma
+    libc.src.math.f16fmaf
+    libc.src.math.f16fmal
+    libc.src.math.f16mul
+    libc.src.math.f16mulf
+    libc.src.math.f16mull
+    libc.src.math.f16sqrt
+    libc.src.math.f16sqrtf
+    libc.src.math.f16sqrtl
+    libc.src.math.f16sub
+    libc.src.math.f16subf
+    libc.src.math.f16subl
+    libc.src.math.fabsf16
+    libc.src.math.fdimf16
+    libc.src.math.floorf16
+    libc.src.math.fmaxf16
+    libc.src.math.fmaximum_mag_numf16
+    libc.src.math.fmaximum_magf16
+    libc.src.math.fmaximum_numf16
+    libc.src.math.fmaximumf16
+    libc.src.math.fminf16
+    libc.src.math.fminimum_mag_numf16
+    libc.src.math.fminimum_magf16
+    libc.src.math.fminimum_numf16
+    libc.src.math.fminimumf16
+    libc.src.math.fmodf16
+    libc.src.math.frexpf16
+    libc.src.math.fromfpf16
+    libc.src.math.fromfpxf16
+    libc.src.math.getpayloadf16
+    libc.src.math.ilogbf16
+    libc.src.math.ldexpf16
+    libc.src.math.llogbf16
+    libc.src.math.llrintf16
+    libc.src.math.llroundf16
+    libc.src.math.log10f16
+    libc.src.math.log2f16
+    libc.src.math.logbf16
+    libc.src.math.logf16
+    libc.src.math.lrintf16
+    libc.src.math.lroundf16
+    libc.src.math.modff16
+    libc.src.math.nanf16
+    libc.src.math.nearbyintf16
+    libc.src.math.nextafterf16
+    libc.src.math.nextdownf16
+    libc.src.math.nexttowardf16
+    libc.src.math.nextupf16
+    libc.src.math.remainderf16
+    libc.src.math.remquof16
+    libc.src.math.rintf16
+    libc.src.math.roundevenf16
+    libc.src.math.roundf16
+    libc.src.math.scalblnf16
+    libc.src.math.scalbnf16
+    libc.src.math.setpayloadf16
+    libc.src.math.setpayloadsigf16
+    libc.src.math.sinhf16
+    libc.src.math.sqrtf16
+    libc.src.math.tanhf16
+    libc.src.math.totalorderf16
+    libc.src.math.totalordermagf16
+    libc.src.math.truncf16
+    libc.src.math.ufromfpf16
+    libc.src.math.ufromfpxf16
+  )
+endif()
+
+set(TARGET_LLVMLIBC_ENTRYPOINTS
+  ${TARGET_LIBC_ENTRYPOINTS}
+  ${TARGET_LIBM_ENTRYPOINTS}
+)
diff --git a/libc/config/gpu/spirv64/headers.txt b/libc/config/gpu/s...
[truncated]

Copy link

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff 72791fef6d6c84b72cb961b288b25283bea97310 874f408032cdb12188810a06c9b68d90c35deecb --extensions cpp,c,h -- libc/src/math/spirv64/acos.cpp libc/src/math/spirv64/acosf.cpp libc/src/math/spirv64/acosh.cpp libc/src/math/spirv64/acoshf.cpp libc/src/math/spirv64/asin.cpp libc/src/math/spirv64/asinf.cpp libc/src/math/spirv64/asinh.cpp libc/src/math/spirv64/asinhf.cpp libc/src/math/spirv64/atan.cpp libc/src/math/spirv64/atan2.cpp libc/src/math/spirv64/atan2f.cpp libc/src/math/spirv64/atanf.cpp libc/src/math/spirv64/atanh.cpp libc/src/math/spirv64/atanhf.cpp libc/src/math/spirv64/ceil.cpp libc/src/math/spirv64/ceilf.cpp libc/src/math/spirv64/copysign.cpp libc/src/math/spirv64/copysignf.cpp libc/src/math/spirv64/cos.cpp libc/src/math/spirv64/cosf.cpp libc/src/math/spirv64/cosh.cpp libc/src/math/spirv64/coshf.cpp libc/src/math/spirv64/declarations.h libc/src/math/spirv64/erf.cpp libc/src/math/spirv64/erff.cpp libc/src/math/spirv64/exp.cpp libc/src/math/spirv64/exp10.cpp libc/src/math/spirv64/exp10f.cpp libc/src/math/spirv64/exp2.cpp libc/src/math/spirv64/exp2f.cpp libc/src/math/spirv64/expf.cpp libc/src/math/spirv64/expm1.cpp libc/src/math/spirv64/expm1f.cpp libc/src/math/spirv64/fabs.cpp libc/src/math/spirv64/fabsf.cpp libc/src/math/spirv64/fdim.cpp libc/src/math/spirv64/fdimf.cpp libc/src/math/spirv64/floor.cpp libc/src/math/spirv64/floorf.cpp libc/src/math/spirv64/fma.cpp libc/src/math/spirv64/fmaf.cpp libc/src/math/spirv64/fmax.cpp libc/src/math/spirv64/fmaxf.cpp libc/src/math/spirv64/fmin.cpp libc/src/math/spirv64/fminf.cpp libc/src/math/spirv64/fmod.cpp libc/src/math/spirv64/fmodf.cpp libc/src/math/spirv64/frexp.cpp libc/src/math/spirv64/frexpf.cpp libc/src/math/spirv64/hypot.cpp libc/src/math/spirv64/hypotf.cpp libc/src/math/spirv64/ilogb.cpp libc/src/math/spirv64/ilogbf.cpp libc/src/math/spirv64/ldexp.cpp libc/src/math/spirv64/ldexpf.cpp libc/src/math/spirv64/lgamma.cpp libc/src/math/spirv64/lgamma_r.cpp libc/src/math/spirv64/llrint.cpp libc/src/math/spirv64/llrintf.cpp libc/src/math/spirv64/log.cpp libc/src/math/spirv64/log10.cpp libc/src/math/spirv64/log10f.cpp libc/src/math/spirv64/log1p.cpp libc/src/math/spirv64/log1pf.cpp libc/src/math/spirv64/log2.cpp libc/src/math/spirv64/log2f.cpp libc/src/math/spirv64/logb.cpp libc/src/math/spirv64/logbf.cpp libc/src/math/spirv64/logf.cpp libc/src/math/spirv64/lrint.cpp libc/src/math/spirv64/lrintf.cpp libc/src/math/spirv64/nearbyint.cpp libc/src/math/spirv64/nearbyintf.cpp libc/src/math/spirv64/nextafter.cpp libc/src/math/spirv64/nextafterf.cpp libc/src/math/spirv64/platform.h libc/src/math/spirv64/powf.cpp libc/src/math/spirv64/powi.cpp libc/src/math/spirv64/powif.cpp libc/src/math/spirv64/remainder.cpp libc/src/math/spirv64/remainderf.cpp libc/src/math/spirv64/remquo.cpp libc/src/math/spirv64/remquof.cpp libc/src/math/spirv64/rint.cpp libc/src/math/spirv64/rintf.cpp libc/src/math/spirv64/round.cpp libc/src/math/spirv64/roundf.cpp libc/src/math/spirv64/scalbn.cpp libc/src/math/spirv64/scalbnf.cpp libc/src/math/spirv64/sin.cpp libc/src/math/spirv64/sincos.cpp libc/src/math/spirv64/sincosf.cpp libc/src/math/spirv64/sinf.cpp libc/src/math/spirv64/sinh.cpp libc/src/math/spirv64/sinhf.cpp libc/src/math/spirv64/sqrt.cpp libc/src/math/spirv64/sqrtf.cpp libc/src/math/spirv64/tan.cpp libc/src/math/spirv64/tanf.cpp libc/src/math/spirv64/tanh.cpp libc/src/math/spirv64/tanhf.cpp libc/src/math/spirv64/tgamma.cpp libc/src/math/spirv64/tgammaf.cpp libc/src/math/spirv64/trunc.cpp libc/src/math/spirv64/truncf.cpp libc/startup/gpu/spirv64/start.cpp clang/lib/Basic/Targets/SPIR.h lld/ELF/InputFiles.cpp offload/DeviceRTL/include/State.h offload/DeviceRTL/src/State.cpp offload/test/offloading/bug64959.c
View the diff from clang-format here.
diff --git a/libc/startup/gpu/spirv64/start.cpp b/libc/startup/gpu/spirv64/start.cpp
index b1cb9f7be0..6b5272609d 100644
--- a/libc/startup/gpu/spirv64/start.cpp
+++ b/libc/startup/gpu/spirv64/start.cpp
@@ -47,11 +47,11 @@ static void call_fini_array_callbacks() {
 // spirv is rejecting amdgpu_kernel, kernel and __kernel
 // clang suggests it wants kernels marked with something from opencl
 
-extern "C" [[gnu::visibility("protected")/*, clang::amdgpu_kernel,
-             clang::amdgpu_flat_work_group_size(1, 1),
-             clang::amdgpu_max_num_work_groups(1)*/]]
-void
-_begin(int argc, char **argv, char **env) {
+extern "C" [[gnu::visibility("protected") /*, clang::amdgpu_kernel,
+              clang::amdgpu_flat_work_group_size(1, 1),
+              clang::amdgpu_max_num_work_groups(1)*/
+]]
+void _begin(int argc, char **argv, char **env) {
   __atomic_store_n(&LIBC_NAMESPACE::app.env_ptr,
                    reinterpret_cast<uintptr_t *>(env), __ATOMIC_RELAXED);
   // We want the fini array callbacks to be run after other atexit
@@ -62,16 +62,17 @@ _begin(int argc, char **argv, char **env) {
   LIBC_NAMESPACE::call_init_array_callbacks(argc, argv, env);
 }
 
-extern "C" [[gnu::visibility("protected")/*, clang::amdgpu_kernel*/]] void
+extern "C" [[gnu::visibility("protected") /*, clang::amdgpu_kernel*/]] void
 _start(int argc, char **argv, char **envp, int *ret) {
   // Invoke the 'main' function with every active thread that the user launched
   // the _start kernel with.
   __atomic_fetch_or(ret, main(argc, argv, envp), __ATOMIC_RELAXED);
 }
 
-extern "C" [[gnu::visibility("protected")/*, clang::amdgpu_kernel,
-             clang::amdgpu_flat_work_group_size(1, 1),
-             clang::amdgpu_max_num_work_groups(1)*/]] void
+extern "C" [[gnu::visibility("protected") /*, clang::amdgpu_kernel,
+              clang::amdgpu_flat_work_group_size(1, 1),
+              clang::amdgpu_max_num_work_groups(1)*/
+]] void
 _end(int retval) {
   // Only a single thread should call `exit` here, the rest should gracefully
   // return from the kernel. This is so only one thread calls the destructors
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 9549a1c3d4..ff177602fa 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -1680,11 +1680,11 @@ static uint16_t getBitcodeMachineKind(Ctx &ctx, StringRef path,
   case Triple::x86:
     return t.isOSIAMCU() ? EM_IAMCU : EM_386;
   case Triple::x86_64:
-    return EM_X86_64; 
+    return EM_X86_64;
   case Triple::spirv64:
     if (t.getVendor() == Triple::AMD)
       return EM_AMDGPU;
-    LLVM_FALLTHROUGH; 
+    LLVM_FALLTHROUGH;
   default:
     ErrAlways(ctx) << path
                    << ": could not infer e_machine from bitcode target triple "
diff --git a/offload/DeviceRTL/include/State.h b/offload/DeviceRTL/include/State.h
index 54bcb9cf79..f36be1ef2e 100644
--- a/offload/DeviceRTL/include/State.h
+++ b/offload/DeviceRTL/include/State.h
@@ -104,19 +104,16 @@ struct ThreadStateTy {
   void init() {
     // assignment relies on implicit conversion between address spaces
     // ICVState = TeamState.ICVState;
-    __builtin_memcpy(&ICVState,
-                     &TeamState.ICVState,
-                     sizeof(ICVState));
+    __builtin_memcpy(&ICVState, &TeamState.ICVState, sizeof(ICVState));
     PreviousThreadState = nullptr;
   }
 
   void init(ThreadStateTy *PreviousTS) {
     __builtin_memcpy(&ICVState,
-                     PreviousTS ?
-                     (state::ICVStateTy*) & PreviousTS->ICVState
-                     : (state::ICVStateTy*) &TeamState.ICVState,
+                     PreviousTS ? (state::ICVStateTy *)&PreviousTS->ICVState
+                                : (state::ICVStateTy *)&TeamState.ICVState,
                      sizeof(ICVState));
-    
+
     PreviousThreadState = PreviousTS;
   }
 };
@@ -178,7 +175,7 @@ void resetStateForThread(uint32_t TId);
       TeamState.HasThreadState = true;                                         \
       ThreadStates[TId]->init();                                               \
     }                                                                          \
-    return (uint32_t &)ThreadStates[TId]->ICVState.Member;              \
+    return (uint32_t &)ThreadStates[TId]->ICVState.Member;                     \
   }
 
 // FIXME: https://github.com/llvm/llvm-project/issues/123241.
@@ -187,8 +184,8 @@ void resetStateForThread(uint32_t TId);
     auto TId = mapping::getThreadIdInBlock();                                  \
     if (OMP_UNLIKELY(!ForceTeamState && config::mayUseThreadStates() &&        \
                      TeamState.HasThreadState && ThreadStates[TId]))           \
-      return (uint32_t &)ThreadStates[TId]->ICVState.Member;            \
-    return (uint32_t &)TeamState.ICVState.Member;                       \
+      return (uint32_t &)ThreadStates[TId]->ICVState.Member;                   \
+    return (uint32_t &)TeamState.ICVState.Member;                              \
   }
 
 [[gnu::always_inline, gnu::flatten]] inline uint32_t &
diff --git a/offload/DeviceRTL/src/State.cpp b/offload/DeviceRTL/src/State.cpp
index fe7fab0ef8..143e8f8578 100644
--- a/offload/DeviceRTL/src/State.cpp
+++ b/offload/DeviceRTL/src/State.cpp
@@ -316,20 +316,18 @@ void state::resetStateForThread(uint32_t TId) {
 void state::runAndCheckState(void(Func(void))) {
   // TeamStateTy OldTeamState = TeamState;
   TeamStateTy OldTeamState;
-  __builtin_memcpy(&OldTeamState,
-                   &TeamState,
-                   sizeof(TeamStateTy));
-  OldTeamState.assertEqual((TeamStateTy&)TeamState);
+  __builtin_memcpy(&OldTeamState, &TeamState, sizeof(TeamStateTy));
+  OldTeamState.assertEqual((TeamStateTy &)TeamState);
 
   Func();
 
-  OldTeamState.assertEqual((TeamStateTy&)TeamState);
+  OldTeamState.assertEqual((TeamStateTy &)TeamState);
 }
 
 void state::assumeInitialState(bool IsSPMD) {
   TeamStateTy InitialTeamState;
   InitialTeamState.init(IsSPMD);
-  InitialTeamState.assertEqual((TeamStateTy&)TeamState);
+  InitialTeamState.assertEqual((TeamStateTy &)TeamState);
   ASSERT(mapping::isSPMDMode() == IsSPMD, nullptr);
 }
 
@@ -466,7 +464,8 @@ constexpr uint64_t NUM_SHARED_VARIABLES_IN_SHARED_MEM = 64;
 
 void __kmpc_begin_sharing_variables(void ***GlobalArgs, uint64_t nArgs) {
   if (nArgs <= NUM_SHARED_VARIABLES_IN_SHARED_MEM) {
-    SharedMemVariableSharingSpacePtr = (void**)&SharedMemVariableSharingSpace[0];
+    SharedMemVariableSharingSpacePtr =
+        (void **)&SharedMemVariableSharingSpace[0];
   } else {
     SharedMemVariableSharingSpacePtr = (void **)memory::allocGlobal(
         nArgs * sizeof(void *), "new extended args");
@@ -477,7 +476,8 @@ void __kmpc_begin_sharing_variables(void ***GlobalArgs, uint64_t nArgs) {
 }
 
 void __kmpc_end_sharing_variables() {
-  if ((void*)SharedMemVariableSharingSpacePtr != (void*)&SharedMemVariableSharingSpace[0])
+  if ((void *)SharedMemVariableSharingSpacePtr !=
+      (void *)&SharedMemVariableSharingSpace[0])
     memory::freeGlobal(SharedMemVariableSharingSpacePtr, "new extended args");
 }
 

@farzonl
Copy link
Member

farzonl commented Feb 25, 2025

@JonChesterfield even if you distinguish spirv64 from amdgpu in cmake clang
doesn't make that distinction. A common pattern for spriv64 is to return null if its not AMDGPU.

clang/lib/CodeGen/CGBuiltin.cpp

case llvm::Triple::spirv64:
    if (CGF->getTarget().getTriple().getOS() != llvm::Triple::OSType::AMDHSA)
      return nullptr;
    return CGF->EmitAMDGPUBuiltinExpr(BuiltinID, E);

clang/lib/Basic/Targets.cpp

case llvm::Triple::spirv64: {
    if (os != llvm::Triple::UnknownOS ||
        Triple.getEnvironment() != llvm::Triple::UnknownEnvironment) {
      if (os == llvm::Triple::OSType::AMDHSA)
        return std::make_unique<SPIRV64AMDGCNTargetInfo>(Triple, Opts);
      return nullptr;
    }
  }

@jhuber6
Copy link
Contributor

jhuber6 commented Feb 25, 2025

@JonChesterfield even if you distinguish spirv64 from amdgpu in cmake clang doesn't make that distinction. A common pattern for spriv64 is to return null if its not AMDGPU.

General question, what's the expected way to access things like thread IDs and such from SPIR-V? The presence of the spirv64-- and spirv64-amd-amdhsa confuses me, since I would've assumed that SPIR-V would have some builtins, but as far as I can tell the current state of the art is just to emit builtins that the underlying target uses, like AMD. At that point, what's the benefit of SPIR-V compared to LLVM-IR?

@llvmbot llvmbot added flang:openmp llvm:ir clang:openmp OpenMP related changes to Clang labels Mar 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:openmp OpenMP related changes to Clang clang Clang issues not falling into any other category flang:openmp libc lld:ELF lld llvm:ir offload
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants