xref: /openbsd-src/gnu/llvm/clang/lib/Headers/__clang_cuda_cmath.h (revision a9ac8606c53d55cee9c3a39778b249c51df111ef)
1e5dd7070Spatrick /*===---- __clang_cuda_cmath.h - Device-side CUDA cmath support ------------===
2e5dd7070Spatrick  *
3e5dd7070Spatrick  * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick  * See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick  *
7e5dd7070Spatrick  *===-----------------------------------------------------------------------===
8e5dd7070Spatrick  */
9e5dd7070Spatrick #ifndef __CLANG_CUDA_CMATH_H__
10e5dd7070Spatrick #define __CLANG_CUDA_CMATH_H__
11e5dd7070Spatrick #ifndef __CUDA__
12e5dd7070Spatrick #error "This file is for CUDA compilation only."
13e5dd7070Spatrick #endif
14e5dd7070Spatrick 
15ec727ea7Spatrick #ifndef __OPENMP_NVPTX__
16e5dd7070Spatrick #include <limits>
17ec727ea7Spatrick #endif
18e5dd7070Spatrick 
19e5dd7070Spatrick // CUDA lets us use various std math functions on the device side.  This file
20e5dd7070Spatrick // works in concert with __clang_cuda_math_forward_declares.h to make this work.
21e5dd7070Spatrick //
22e5dd7070Spatrick // Specifically, the forward-declares header declares __device__ overloads for
23e5dd7070Spatrick // these functions in the global namespace, then pulls them into namespace std
24e5dd7070Spatrick // with 'using' statements.  Then this file implements those functions, after
25e5dd7070Spatrick // their implementations have been pulled in.
26e5dd7070Spatrick //
27e5dd7070Spatrick // It's important that we declare the functions in the global namespace and pull
28e5dd7070Spatrick // them into namespace std with using statements, as opposed to simply declaring
29e5dd7070Spatrick // these functions in namespace std, because our device functions need to
30e5dd7070Spatrick // overload the standard library functions, which may be declared in the global
31e5dd7070Spatrick // namespace or in std, depending on the degree of conformance of the stdlib
32e5dd7070Spatrick // implementation.  Declaring in the global namespace and pulling into namespace
33e5dd7070Spatrick // std covers all of the known knowns.
34e5dd7070Spatrick 
35ec727ea7Spatrick #ifdef __OPENMP_NVPTX__
36ec727ea7Spatrick #define __DEVICE__ static constexpr __attribute__((always_inline, nothrow))
37e5dd7070Spatrick #else
38e5dd7070Spatrick #define __DEVICE__ static __device__ __inline__ __attribute__((always_inline))
39e5dd7070Spatrick #endif
40e5dd7070Spatrick 
abs(long long __n)41e5dd7070Spatrick __DEVICE__ long long abs(long long __n) { return ::llabs(__n); }
abs(long __n)42e5dd7070Spatrick __DEVICE__ long abs(long __n) { return ::labs(__n); }
abs(float __x)43e5dd7070Spatrick __DEVICE__ float abs(float __x) { return ::fabsf(__x); }
abs(double __x)44e5dd7070Spatrick __DEVICE__ double abs(double __x) { return ::fabs(__x); }
acos(float __x)45e5dd7070Spatrick __DEVICE__ float acos(float __x) { return ::acosf(__x); }
asin(float __x)46e5dd7070Spatrick __DEVICE__ float asin(float __x) { return ::asinf(__x); }
atan(float __x)47e5dd7070Spatrick __DEVICE__ float atan(float __x) { return ::atanf(__x); }
atan2(float __x,float __y)48e5dd7070Spatrick __DEVICE__ float atan2(float __x, float __y) { return ::atan2f(__x, __y); }
ceil(float __x)49e5dd7070Spatrick __DEVICE__ float ceil(float __x) { return ::ceilf(__x); }
cos(float __x)50e5dd7070Spatrick __DEVICE__ float cos(float __x) { return ::cosf(__x); }
cosh(float __x)51e5dd7070Spatrick __DEVICE__ float cosh(float __x) { return ::coshf(__x); }
exp(float __x)52e5dd7070Spatrick __DEVICE__ float exp(float __x) { return ::expf(__x); }
fabs(float __x)53ec727ea7Spatrick __DEVICE__ float fabs(float __x) { return ::fabsf(__x); }
floor(float __x)54e5dd7070Spatrick __DEVICE__ float floor(float __x) { return ::floorf(__x); }
fmod(float __x,float __y)55e5dd7070Spatrick __DEVICE__ float fmod(float __x, float __y) { return ::fmodf(__x, __y); }
fpclassify(float __x)56e5dd7070Spatrick __DEVICE__ int fpclassify(float __x) {
57e5dd7070Spatrick   return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL,
58e5dd7070Spatrick                               FP_ZERO, __x);
59e5dd7070Spatrick }
fpclassify(double __x)60e5dd7070Spatrick __DEVICE__ int fpclassify(double __x) {
61e5dd7070Spatrick   return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL,
62e5dd7070Spatrick                               FP_ZERO, __x);
63e5dd7070Spatrick }
frexp(float __arg,int * __exp)64e5dd7070Spatrick __DEVICE__ float frexp(float __arg, int *__exp) {
65e5dd7070Spatrick   return ::frexpf(__arg, __exp);
66e5dd7070Spatrick }
67e5dd7070Spatrick 
68e5dd7070Spatrick // For inscrutable reasons, the CUDA headers define these functions for us on
69*a9ac8606Spatrick // Windows.
70*a9ac8606Spatrick #if !defined(_MSC_VER) || defined(__OPENMP_NVPTX__)
71*a9ac8606Spatrick 
72*a9ac8606Spatrick // For OpenMP we work around some old system headers that have non-conforming
73*a9ac8606Spatrick // `isinf(float)` and `isnan(float)` implementations that return an `int`. We do
74*a9ac8606Spatrick // this by providing two versions of these functions, differing only in the
75*a9ac8606Spatrick // return type. To avoid conflicting definitions we disable implicit base
76*a9ac8606Spatrick // function generation. That means we will end up with two specializations, one
77*a9ac8606Spatrick // per type, but only one has a base function defined by the system header.
78*a9ac8606Spatrick #if defined(__OPENMP_NVPTX__)
79*a9ac8606Spatrick #pragma omp begin declare variant match(                                       \
80*a9ac8606Spatrick     implementation = {extension(disable_implicit_base)})
81*a9ac8606Spatrick 
82*a9ac8606Spatrick // FIXME: We lack an extension to customize the mangling of the variants, e.g.,
83*a9ac8606Spatrick //        add a suffix. This means we would clash with the names of the variants
84*a9ac8606Spatrick //        (note that we do not create implicit base functions here). To avoid
85*a9ac8606Spatrick //        this clash we add a new trait to some of them that is always true
86*a9ac8606Spatrick //        (this is LLVM after all ;)). It will only influence the mangled name
87*a9ac8606Spatrick //        of the variants inside the inner region and avoid the clash.
88*a9ac8606Spatrick #pragma omp begin declare variant match(implementation = {vendor(llvm)})
89*a9ac8606Spatrick 
isinf(float __x)90*a9ac8606Spatrick __DEVICE__ int isinf(float __x) { return ::__isinff(__x); }
isinf(double __x)91*a9ac8606Spatrick __DEVICE__ int isinf(double __x) { return ::__isinf(__x); }
isfinite(float __x)92*a9ac8606Spatrick __DEVICE__ int isfinite(float __x) { return ::__finitef(__x); }
isfinite(double __x)93*a9ac8606Spatrick __DEVICE__ int isfinite(double __x) { return ::__isfinited(__x); }
isnan(float __x)94*a9ac8606Spatrick __DEVICE__ int isnan(float __x) { return ::__isnanf(__x); }
isnan(double __x)95*a9ac8606Spatrick __DEVICE__ int isnan(double __x) { return ::__isnan(__x); }
96*a9ac8606Spatrick 
97*a9ac8606Spatrick #pragma omp end declare variant
98*a9ac8606Spatrick 
99*a9ac8606Spatrick #endif
100*a9ac8606Spatrick 
isinf(float __x)101e5dd7070Spatrick __DEVICE__ bool isinf(float __x) { return ::__isinff(__x); }
isinf(double __x)102e5dd7070Spatrick __DEVICE__ bool isinf(double __x) { return ::__isinf(__x); }
isfinite(float __x)103e5dd7070Spatrick __DEVICE__ bool isfinite(float __x) { return ::__finitef(__x); }
104e5dd7070Spatrick // For inscrutable reasons, __finite(), the double-precision version of
105e5dd7070Spatrick // __finitef, does not exist when compiling for MacOS.  __isfinited is available
106e5dd7070Spatrick // everywhere and is just as good.
isfinite(double __x)107e5dd7070Spatrick __DEVICE__ bool isfinite(double __x) { return ::__isfinited(__x); }
isnan(float __x)108e5dd7070Spatrick __DEVICE__ bool isnan(float __x) { return ::__isnanf(__x); }
isnan(double __x)109e5dd7070Spatrick __DEVICE__ bool isnan(double __x) { return ::__isnan(__x); }
110*a9ac8606Spatrick 
111*a9ac8606Spatrick #if defined(__OPENMP_NVPTX__)
112*a9ac8606Spatrick #pragma omp end declare variant
113*a9ac8606Spatrick #endif
114*a9ac8606Spatrick 
115e5dd7070Spatrick #endif
116e5dd7070Spatrick 
isgreater(float __x,float __y)117e5dd7070Spatrick __DEVICE__ bool isgreater(float __x, float __y) {
118e5dd7070Spatrick   return __builtin_isgreater(__x, __y);
119e5dd7070Spatrick }
isgreater(double __x,double __y)120e5dd7070Spatrick __DEVICE__ bool isgreater(double __x, double __y) {
121e5dd7070Spatrick   return __builtin_isgreater(__x, __y);
122e5dd7070Spatrick }
isgreaterequal(float __x,float __y)123e5dd7070Spatrick __DEVICE__ bool isgreaterequal(float __x, float __y) {
124e5dd7070Spatrick   return __builtin_isgreaterequal(__x, __y);
125e5dd7070Spatrick }
isgreaterequal(double __x,double __y)126e5dd7070Spatrick __DEVICE__ bool isgreaterequal(double __x, double __y) {
127e5dd7070Spatrick   return __builtin_isgreaterequal(__x, __y);
128e5dd7070Spatrick }
isless(float __x,float __y)129e5dd7070Spatrick __DEVICE__ bool isless(float __x, float __y) {
130e5dd7070Spatrick   return __builtin_isless(__x, __y);
131e5dd7070Spatrick }
isless(double __x,double __y)132e5dd7070Spatrick __DEVICE__ bool isless(double __x, double __y) {
133e5dd7070Spatrick   return __builtin_isless(__x, __y);
134e5dd7070Spatrick }
islessequal(float __x,float __y)135e5dd7070Spatrick __DEVICE__ bool islessequal(float __x, float __y) {
136e5dd7070Spatrick   return __builtin_islessequal(__x, __y);
137e5dd7070Spatrick }
islessequal(double __x,double __y)138e5dd7070Spatrick __DEVICE__ bool islessequal(double __x, double __y) {
139e5dd7070Spatrick   return __builtin_islessequal(__x, __y);
140e5dd7070Spatrick }
islessgreater(float __x,float __y)141e5dd7070Spatrick __DEVICE__ bool islessgreater(float __x, float __y) {
142e5dd7070Spatrick   return __builtin_islessgreater(__x, __y);
143e5dd7070Spatrick }
islessgreater(double __x,double __y)144e5dd7070Spatrick __DEVICE__ bool islessgreater(double __x, double __y) {
145e5dd7070Spatrick   return __builtin_islessgreater(__x, __y);
146e5dd7070Spatrick }
isnormal(float __x)147e5dd7070Spatrick __DEVICE__ bool isnormal(float __x) { return __builtin_isnormal(__x); }
isnormal(double __x)148e5dd7070Spatrick __DEVICE__ bool isnormal(double __x) { return __builtin_isnormal(__x); }
isunordered(float __x,float __y)149e5dd7070Spatrick __DEVICE__ bool isunordered(float __x, float __y) {
150e5dd7070Spatrick   return __builtin_isunordered(__x, __y);
151e5dd7070Spatrick }
isunordered(double __x,double __y)152e5dd7070Spatrick __DEVICE__ bool isunordered(double __x, double __y) {
153e5dd7070Spatrick   return __builtin_isunordered(__x, __y);
154e5dd7070Spatrick }
ldexp(float __arg,int __exp)155e5dd7070Spatrick __DEVICE__ float ldexp(float __arg, int __exp) {
156e5dd7070Spatrick   return ::ldexpf(__arg, __exp);
157e5dd7070Spatrick }
log(float __x)158e5dd7070Spatrick __DEVICE__ float log(float __x) { return ::logf(__x); }
log10(float __x)159e5dd7070Spatrick __DEVICE__ float log10(float __x) { return ::log10f(__x); }
modf(float __x,float * __iptr)160e5dd7070Spatrick __DEVICE__ float modf(float __x, float *__iptr) { return ::modff(__x, __iptr); }
pow(float __base,float __exp)161e5dd7070Spatrick __DEVICE__ float pow(float __base, float __exp) {
162e5dd7070Spatrick   return ::powf(__base, __exp);
163e5dd7070Spatrick }
pow(float __base,int __iexp)164e5dd7070Spatrick __DEVICE__ float pow(float __base, int __iexp) {
165e5dd7070Spatrick   return ::powif(__base, __iexp);
166e5dd7070Spatrick }
pow(double __base,int __iexp)167e5dd7070Spatrick __DEVICE__ double pow(double __base, int __iexp) {
168e5dd7070Spatrick   return ::powi(__base, __iexp);
169e5dd7070Spatrick }
signbit(float __x)170e5dd7070Spatrick __DEVICE__ bool signbit(float __x) { return ::__signbitf(__x); }
signbit(double __x)171e5dd7070Spatrick __DEVICE__ bool signbit(double __x) { return ::__signbitd(__x); }
sin(float __x)172e5dd7070Spatrick __DEVICE__ float sin(float __x) { return ::sinf(__x); }
sinh(float __x)173e5dd7070Spatrick __DEVICE__ float sinh(float __x) { return ::sinhf(__x); }
sqrt(float __x)174e5dd7070Spatrick __DEVICE__ float sqrt(float __x) { return ::sqrtf(__x); }
tan(float __x)175e5dd7070Spatrick __DEVICE__ float tan(float __x) { return ::tanf(__x); }
tanh(float __x)176e5dd7070Spatrick __DEVICE__ float tanh(float __x) { return ::tanhf(__x); }
177e5dd7070Spatrick 
178*a9ac8606Spatrick // There was a redefinition error for this this overload in CUDA mode.
179*a9ac8606Spatrick // We restrict it to OpenMP mode for now, that is where it is actually needed
180*a9ac8606Spatrick // anyway.
181*a9ac8606Spatrick #ifdef __OPENMP_NVPTX__
remquo(float __n,float __d,int * __q)182*a9ac8606Spatrick __DEVICE__ float remquo(float __n, float __d, int *__q) {
183*a9ac8606Spatrick   return ::remquof(__n, __d, __q);
184*a9ac8606Spatrick }
185*a9ac8606Spatrick #endif
186*a9ac8606Spatrick 
187e5dd7070Spatrick // Notably missing above is nexttoward.  We omit it because
188e5dd7070Spatrick // libdevice doesn't provide an implementation, and we don't want to be in the
189e5dd7070Spatrick // business of implementing tricky libm functions in this header.
190e5dd7070Spatrick 
191ec727ea7Spatrick #ifndef __OPENMP_NVPTX__
192ec727ea7Spatrick 
193e5dd7070Spatrick // Now we've defined everything we promised we'd define in
194e5dd7070Spatrick // __clang_cuda_math_forward_declares.h.  We need to do two additional things to
195e5dd7070Spatrick // fix up our math functions.
196e5dd7070Spatrick //
197e5dd7070Spatrick // 1) Define __device__ overloads for e.g. sin(int).  The CUDA headers define
198e5dd7070Spatrick //    only sin(float) and sin(double), which means that e.g. sin(0) is
199e5dd7070Spatrick //    ambiguous.
200e5dd7070Spatrick //
201e5dd7070Spatrick // 2) Pull the __device__ overloads of "foobarf" math functions into namespace
202e5dd7070Spatrick //    std.  These are defined in the CUDA headers in the global namespace,
203e5dd7070Spatrick //    independent of everything else we've done here.
204e5dd7070Spatrick 
205e5dd7070Spatrick // We can't use std::enable_if, because we want to be pre-C++11 compatible.  But
206e5dd7070Spatrick // we go ahead and unconditionally define functions that are only available when
207e5dd7070Spatrick // compiling for C++11 to match the behavior of the CUDA headers.
208e5dd7070Spatrick template<bool __B, class __T = void>
209e5dd7070Spatrick struct __clang_cuda_enable_if {};
210e5dd7070Spatrick 
211e5dd7070Spatrick template <class __T> struct __clang_cuda_enable_if<true, __T> {
212e5dd7070Spatrick   typedef __T type;
213e5dd7070Spatrick };
214e5dd7070Spatrick 
215e5dd7070Spatrick // Defines an overload of __fn that accepts one integral argument, calls
216e5dd7070Spatrick // __fn((double)x), and returns __retty.
217e5dd7070Spatrick #define __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(__retty, __fn)                      \
218e5dd7070Spatrick   template <typename __T>                                                      \
219e5dd7070Spatrick   __DEVICE__                                                                   \
220e5dd7070Spatrick       typename __clang_cuda_enable_if<std::numeric_limits<__T>::is_integer,    \
221e5dd7070Spatrick                                       __retty>::type                           \
222e5dd7070Spatrick       __fn(__T __x) {                                                          \
223e5dd7070Spatrick     return ::__fn((double)__x);                                                \
224e5dd7070Spatrick   }
225e5dd7070Spatrick 
226e5dd7070Spatrick // Defines an overload of __fn that accepts one two arithmetic arguments, calls
227e5dd7070Spatrick // __fn((double)x, (double)y), and returns a double.
228e5dd7070Spatrick //
229e5dd7070Spatrick // Note this is different from OVERLOAD_1, which generates an overload that
230e5dd7070Spatrick // accepts only *integral* arguments.
231e5dd7070Spatrick #define __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(__retty, __fn)                      \
232e5dd7070Spatrick   template <typename __T1, typename __T2>                                      \
233e5dd7070Spatrick   __DEVICE__ typename __clang_cuda_enable_if<                                  \
234e5dd7070Spatrick       std::numeric_limits<__T1>::is_specialized &&                             \
235e5dd7070Spatrick           std::numeric_limits<__T2>::is_specialized,                           \
236e5dd7070Spatrick       __retty>::type                                                           \
237e5dd7070Spatrick   __fn(__T1 __x, __T2 __y) {                                                   \
238e5dd7070Spatrick     return __fn((double)__x, (double)__y);                                     \
239e5dd7070Spatrick   }
240e5dd7070Spatrick 
241e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, acos)
242e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, acosh)
243e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, asin)
244e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, asinh)
245e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, atan)
246e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, atan2);
247e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, atanh)
248e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, cbrt)
249e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, ceil)
250e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, copysign);
251e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, cos)
252e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, cosh)
253e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, erf)
254e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, erfc)
255e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, exp)
256e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, exp2)
257e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, expm1)
258e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, fabs)
259e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, fdim);
260e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, floor)
261e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, fmax);
262e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, fmin);
263e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, fmod);
264e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(int, fpclassify)
265e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, hypot);
266e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(int, ilogb)
267e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(bool, isfinite)
268e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(bool, isgreater);
269e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(bool, isgreaterequal);
270e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(bool, isinf);
271e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(bool, isless);
272e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(bool, islessequal);
273e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(bool, islessgreater);
274e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(bool, isnan);
275e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(bool, isnormal)
276e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(bool, isunordered);
277e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, lgamma)
278e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, log)
279e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, log10)
280e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, log1p)
281e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, log2)
282e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, logb)
283e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(long long, llrint)
284e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(long long, llround)
285e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(long, lrint)
286e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(long, lround)
287e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, nearbyint);
288e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, nextafter);
289e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, pow);
290e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, remainder);
291e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, rint);
292e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, round);
293e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(bool, signbit)
294e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, sin)
295e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, sinh)
296e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, sqrt)
297e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, tan)
298e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, tanh)
299e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, tgamma)
300e5dd7070Spatrick __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, trunc);
301e5dd7070Spatrick 
302e5dd7070Spatrick #undef __CUDA_CLANG_FN_INTEGER_OVERLOAD_1
303e5dd7070Spatrick #undef __CUDA_CLANG_FN_INTEGER_OVERLOAD_2
304e5dd7070Spatrick 
305e5dd7070Spatrick // Overloads for functions that don't match the patterns expected by
306e5dd7070Spatrick // __CUDA_CLANG_FN_INTEGER_OVERLOAD_{1,2}.
307e5dd7070Spatrick template <typename __T1, typename __T2, typename __T3>
308e5dd7070Spatrick __DEVICE__ typename __clang_cuda_enable_if<
309e5dd7070Spatrick     std::numeric_limits<__T1>::is_specialized &&
310e5dd7070Spatrick         std::numeric_limits<__T2>::is_specialized &&
311e5dd7070Spatrick         std::numeric_limits<__T3>::is_specialized,
312e5dd7070Spatrick     double>::type
313e5dd7070Spatrick fma(__T1 __x, __T2 __y, __T3 __z) {
314e5dd7070Spatrick   return std::fma((double)__x, (double)__y, (double)__z);
315e5dd7070Spatrick }
316e5dd7070Spatrick 
317e5dd7070Spatrick template <typename __T>
318e5dd7070Spatrick __DEVICE__ typename __clang_cuda_enable_if<std::numeric_limits<__T>::is_integer,
319e5dd7070Spatrick                                            double>::type
320e5dd7070Spatrick frexp(__T __x, int *__exp) {
321e5dd7070Spatrick   return std::frexp((double)__x, __exp);
322e5dd7070Spatrick }
323e5dd7070Spatrick 
324e5dd7070Spatrick template <typename __T>
325e5dd7070Spatrick __DEVICE__ typename __clang_cuda_enable_if<std::numeric_limits<__T>::is_integer,
326e5dd7070Spatrick                                            double>::type
327e5dd7070Spatrick ldexp(__T __x, int __exp) {
328e5dd7070Spatrick   return std::ldexp((double)__x, __exp);
329e5dd7070Spatrick }
330e5dd7070Spatrick 
331e5dd7070Spatrick template <typename __T1, typename __T2>
332e5dd7070Spatrick __DEVICE__ typename __clang_cuda_enable_if<
333e5dd7070Spatrick     std::numeric_limits<__T1>::is_specialized &&
334e5dd7070Spatrick         std::numeric_limits<__T2>::is_specialized,
335e5dd7070Spatrick     double>::type
336e5dd7070Spatrick remquo(__T1 __x, __T2 __y, int *__quo) {
337e5dd7070Spatrick   return std::remquo((double)__x, (double)__y, __quo);
338e5dd7070Spatrick }
339e5dd7070Spatrick 
340e5dd7070Spatrick template <typename __T>
341e5dd7070Spatrick __DEVICE__ typename __clang_cuda_enable_if<std::numeric_limits<__T>::is_integer,
342e5dd7070Spatrick                                            double>::type
343e5dd7070Spatrick scalbln(__T __x, long __exp) {
344e5dd7070Spatrick   return std::scalbln((double)__x, __exp);
345e5dd7070Spatrick }
346e5dd7070Spatrick 
347e5dd7070Spatrick template <typename __T>
348e5dd7070Spatrick __DEVICE__ typename __clang_cuda_enable_if<std::numeric_limits<__T>::is_integer,
349e5dd7070Spatrick                                            double>::type
350e5dd7070Spatrick scalbn(__T __x, int __exp) {
351e5dd7070Spatrick   return std::scalbn((double)__x, __exp);
352e5dd7070Spatrick }
353e5dd7070Spatrick 
354e5dd7070Spatrick // We need to define these overloads in exactly the namespace our standard
355e5dd7070Spatrick // library uses (including the right inline namespace), otherwise they won't be
356e5dd7070Spatrick // picked up by other functions in the standard library (e.g. functions in
357e5dd7070Spatrick // <complex>).  Thus the ugliness below.
358e5dd7070Spatrick #ifdef _LIBCPP_BEGIN_NAMESPACE_STD
359e5dd7070Spatrick _LIBCPP_BEGIN_NAMESPACE_STD
360e5dd7070Spatrick #else
361e5dd7070Spatrick namespace std {
362e5dd7070Spatrick #ifdef _GLIBCXX_BEGIN_NAMESPACE_VERSION
363e5dd7070Spatrick _GLIBCXX_BEGIN_NAMESPACE_VERSION
364e5dd7070Spatrick #endif
365e5dd7070Spatrick #endif
366e5dd7070Spatrick 
367e5dd7070Spatrick // Pull the new overloads we defined above into namespace std.
368e5dd7070Spatrick using ::acos;
369e5dd7070Spatrick using ::acosh;
370e5dd7070Spatrick using ::asin;
371e5dd7070Spatrick using ::asinh;
372e5dd7070Spatrick using ::atan;
373e5dd7070Spatrick using ::atan2;
374e5dd7070Spatrick using ::atanh;
375e5dd7070Spatrick using ::cbrt;
376e5dd7070Spatrick using ::ceil;
377e5dd7070Spatrick using ::copysign;
378e5dd7070Spatrick using ::cos;
379e5dd7070Spatrick using ::cosh;
380e5dd7070Spatrick using ::erf;
381e5dd7070Spatrick using ::erfc;
382e5dd7070Spatrick using ::exp;
383e5dd7070Spatrick using ::exp2;
384e5dd7070Spatrick using ::expm1;
385e5dd7070Spatrick using ::fabs;
386e5dd7070Spatrick using ::fdim;
387e5dd7070Spatrick using ::floor;
388e5dd7070Spatrick using ::fma;
389e5dd7070Spatrick using ::fmax;
390e5dd7070Spatrick using ::fmin;
391e5dd7070Spatrick using ::fmod;
392e5dd7070Spatrick using ::fpclassify;
393e5dd7070Spatrick using ::frexp;
394e5dd7070Spatrick using ::hypot;
395e5dd7070Spatrick using ::ilogb;
396e5dd7070Spatrick using ::isfinite;
397e5dd7070Spatrick using ::isgreater;
398e5dd7070Spatrick using ::isgreaterequal;
399e5dd7070Spatrick using ::isless;
400e5dd7070Spatrick using ::islessequal;
401e5dd7070Spatrick using ::islessgreater;
402e5dd7070Spatrick using ::isnormal;
403e5dd7070Spatrick using ::isunordered;
404e5dd7070Spatrick using ::ldexp;
405e5dd7070Spatrick using ::lgamma;
406e5dd7070Spatrick using ::llrint;
407e5dd7070Spatrick using ::llround;
408e5dd7070Spatrick using ::log;
409e5dd7070Spatrick using ::log10;
410e5dd7070Spatrick using ::log1p;
411e5dd7070Spatrick using ::log2;
412e5dd7070Spatrick using ::logb;
413e5dd7070Spatrick using ::lrint;
414e5dd7070Spatrick using ::lround;
415e5dd7070Spatrick using ::nearbyint;
416e5dd7070Spatrick using ::nextafter;
417e5dd7070Spatrick using ::pow;
418e5dd7070Spatrick using ::remainder;
419e5dd7070Spatrick using ::remquo;
420e5dd7070Spatrick using ::rint;
421e5dd7070Spatrick using ::round;
422e5dd7070Spatrick using ::scalbln;
423e5dd7070Spatrick using ::scalbn;
424e5dd7070Spatrick using ::signbit;
425e5dd7070Spatrick using ::sin;
426e5dd7070Spatrick using ::sinh;
427e5dd7070Spatrick using ::sqrt;
428e5dd7070Spatrick using ::tan;
429e5dd7070Spatrick using ::tanh;
430e5dd7070Spatrick using ::tgamma;
431e5dd7070Spatrick using ::trunc;
432e5dd7070Spatrick 
433e5dd7070Spatrick // Well this is fun: We need to pull these symbols in for libc++, but we can't
434e5dd7070Spatrick // pull them in with libstdc++, because its ::isinf and ::isnan are different
435e5dd7070Spatrick // than its std::isinf and std::isnan.
436e5dd7070Spatrick #ifndef __GLIBCXX__
437e5dd7070Spatrick using ::isinf;
438e5dd7070Spatrick using ::isnan;
439e5dd7070Spatrick #endif
440e5dd7070Spatrick 
441e5dd7070Spatrick // Finally, pull the "foobarf" functions that CUDA defines in its headers into
442e5dd7070Spatrick // namespace std.
443e5dd7070Spatrick using ::acosf;
444e5dd7070Spatrick using ::acoshf;
445e5dd7070Spatrick using ::asinf;
446e5dd7070Spatrick using ::asinhf;
447e5dd7070Spatrick using ::atan2f;
448e5dd7070Spatrick using ::atanf;
449e5dd7070Spatrick using ::atanhf;
450e5dd7070Spatrick using ::cbrtf;
451e5dd7070Spatrick using ::ceilf;
452e5dd7070Spatrick using ::copysignf;
453e5dd7070Spatrick using ::cosf;
454e5dd7070Spatrick using ::coshf;
455e5dd7070Spatrick using ::erfcf;
456e5dd7070Spatrick using ::erff;
457e5dd7070Spatrick using ::exp2f;
458e5dd7070Spatrick using ::expf;
459e5dd7070Spatrick using ::expm1f;
460e5dd7070Spatrick using ::fabsf;
461e5dd7070Spatrick using ::fdimf;
462e5dd7070Spatrick using ::floorf;
463e5dd7070Spatrick using ::fmaf;
464e5dd7070Spatrick using ::fmaxf;
465e5dd7070Spatrick using ::fminf;
466e5dd7070Spatrick using ::fmodf;
467e5dd7070Spatrick using ::frexpf;
468e5dd7070Spatrick using ::hypotf;
469e5dd7070Spatrick using ::ilogbf;
470e5dd7070Spatrick using ::ldexpf;
471e5dd7070Spatrick using ::lgammaf;
472e5dd7070Spatrick using ::llrintf;
473e5dd7070Spatrick using ::llroundf;
474e5dd7070Spatrick using ::log10f;
475e5dd7070Spatrick using ::log1pf;
476e5dd7070Spatrick using ::log2f;
477e5dd7070Spatrick using ::logbf;
478e5dd7070Spatrick using ::logf;
479e5dd7070Spatrick using ::lrintf;
480e5dd7070Spatrick using ::lroundf;
481e5dd7070Spatrick using ::modff;
482e5dd7070Spatrick using ::nearbyintf;
483e5dd7070Spatrick using ::nextafterf;
484e5dd7070Spatrick using ::powf;
485e5dd7070Spatrick using ::remainderf;
486e5dd7070Spatrick using ::remquof;
487e5dd7070Spatrick using ::rintf;
488e5dd7070Spatrick using ::roundf;
489e5dd7070Spatrick using ::scalblnf;
490e5dd7070Spatrick using ::scalbnf;
491e5dd7070Spatrick using ::sinf;
492e5dd7070Spatrick using ::sinhf;
493e5dd7070Spatrick using ::sqrtf;
494e5dd7070Spatrick using ::tanf;
495e5dd7070Spatrick using ::tanhf;
496e5dd7070Spatrick using ::tgammaf;
497e5dd7070Spatrick using ::truncf;
498e5dd7070Spatrick 
499e5dd7070Spatrick #ifdef _LIBCPP_END_NAMESPACE_STD
500e5dd7070Spatrick _LIBCPP_END_NAMESPACE_STD
501e5dd7070Spatrick #else
502e5dd7070Spatrick #ifdef _GLIBCXX_BEGIN_NAMESPACE_VERSION
503e5dd7070Spatrick _GLIBCXX_END_NAMESPACE_VERSION
504e5dd7070Spatrick #endif
505e5dd7070Spatrick } // namespace std
506e5dd7070Spatrick #endif
507e5dd7070Spatrick 
508ec727ea7Spatrick #endif // __OPENMP_NVPTX__
509ec727ea7Spatrick 
510e5dd7070Spatrick #undef __DEVICE__
511e5dd7070Spatrick 
512e5dd7070Spatrick #endif
513