diff --git a/libc/config/gpu/entrypoints.txt b/libc/config/gpu/entrypoints.txt --- a/libc/config/gpu/entrypoints.txt +++ b/libc/config/gpu/entrypoints.txt @@ -84,6 +84,7 @@ set(TARGET_LIBM_ENTRYPOINTS # math.h entrypoints libc.src.math.sin + libc.src.math.modf ) set(TARGET_LLVMLIBC_ENTRYPOINTS diff --git a/libc/src/math/gpu/CMakeLists.txt b/libc/src/math/gpu/CMakeLists.txt --- a/libc/src/math/gpu/CMakeLists.txt +++ b/libc/src/math/gpu/CMakeLists.txt @@ -36,3 +36,18 @@ ${bitcode_link_flags} -O2 ) + +add_entrypoint_object( + modf + SRCS + modf.cpp + HDRS + ../modf.h + COMPILE_OPTIONS + # FIXME: We need a way to pass the flag to only the NVTPX / AMDGPU build. + # This shouldn't cause issues because we only link in needed symbols, but it + # will link in identity metadata from both libraries. + -Wno-linker-warnings + ${bitcode_link_flags} + -O2 +) \ No newline at end of file diff --git a/libc/src/math/gpu/amdgpu/amdgpu.h b/libc/src/math/gpu/amdgpu/amdgpu.h --- a/libc/src/math/gpu/amdgpu/amdgpu.h +++ b/libc/src/math/gpu/amdgpu/amdgpu.h @@ -17,6 +17,18 @@ namespace __llvm_libc { namespace vendor { +LIBC_INLINE double modf(double x, double *iptr) { + double tmp; +#ifdef __OPENMP_AMDGCN__ +#pragma omp allocate(tmp) allocator(omp_thread_mem_alloc) +#endif + double r = + __ocml_modf_f64(x, (__attribute__((address_space(5))) double *)&tmp); + *iptr = tmp; + + return r; +} + LIBC_INLINE double sin(double x) { return __ocml_sin_f64(x); } } // namespace vendor diff --git a/libc/src/math/gpu/amdgpu/declarations.h b/libc/src/math/gpu/amdgpu/declarations.h --- a/libc/src/math/gpu/amdgpu/declarations.h +++ b/libc/src/math/gpu/amdgpu/declarations.h @@ -12,6 +12,7 @@ namespace __llvm_libc { extern "C" { +double __ocml_modf_f64(double,double*); double __ocml_sin_f64(double); } diff --git a/libc/src/math/gpu/nvptx/declarations.h b/libc/src/math/gpu/modf.cpp copy from libc/src/math/gpu/nvptx/declarations.h copy to libc/src/math/gpu/modf.cpp --- a/libc/src/math/gpu/nvptx/declarations.h +++ b/libc/src/math/gpu/modf.cpp @@ -1,4 +1,4 @@ -//===-- NVPTX specific declarations for math support ----------------------===// +//===-- Implementation of the modf function for GPU ------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,15 +6,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIBC_SRC_MATH_GPU_NVPTX_DECLARATIONS_H -#define LLVM_LIBC_SRC_MATH_GPU_NVPTX_DECLARATIONS_H +#include "src/math/modf.h" +#include "src/__support/common.h" -namespace __llvm_libc { +#include "common.h" -extern "C" { -double __nv_sin(double); -} +namespace __llvm_libc { -} // namespace __llvm_libc +LLVM_LIBC_FUNCTION(double, modf, (double x,double *iptr)) { return internal::modf(x,iptr); } -#endif // LLVM_LIBC_SRC_MATH_GPU_NVPTX_DECLARATIONS_H +} // namespace __llvm_libc \ No newline at end of file diff --git a/libc/src/math/gpu/nvptx/declarations.h b/libc/src/math/gpu/nvptx/declarations.h --- a/libc/src/math/gpu/nvptx/declarations.h +++ b/libc/src/math/gpu/nvptx/declarations.h @@ -12,6 +12,7 @@ namespace __llvm_libc { extern "C" { +double __nv_modf(double,double*); double __nv_sin(double); } diff --git a/libc/src/math/gpu/nvptx/nvptx.h b/libc/src/math/gpu/nvptx/nvptx.h --- a/libc/src/math/gpu/nvptx/nvptx.h +++ b/libc/src/math/gpu/nvptx/nvptx.h @@ -16,6 +16,7 @@ namespace __llvm_libc { namespace internal { +LIBC_INLINE double modf(double x, double *iptr) { return __nv_modf(x,iptr); } LIBC_INLINE double sin(double x) { return __nv_sin(x); } } // namespace internal