xref: /freebsd/contrib/llvm-project/clang/lib/Headers/__clang_cuda_cmath.h (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
10b57cec5SDimitry Andric /*===---- __clang_cuda_cmath.h - Device-side CUDA cmath support ------------===
20b57cec5SDimitry Andric  *
30b57cec5SDimitry Andric  * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric  * See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric  *
70b57cec5SDimitry Andric  *===-----------------------------------------------------------------------===
80b57cec5SDimitry Andric  */
90b57cec5SDimitry Andric #ifndef __CLANG_CUDA_CMATH_H__
100b57cec5SDimitry Andric #define __CLANG_CUDA_CMATH_H__
110b57cec5SDimitry Andric #ifndef __CUDA__
120b57cec5SDimitry Andric #error "This file is for CUDA compilation only."
130b57cec5SDimitry Andric #endif
140b57cec5SDimitry Andric 
155ffd83dbSDimitry Andric #ifndef __OPENMP_NVPTX__
160b57cec5SDimitry Andric #include <limits>
175ffd83dbSDimitry Andric #endif
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric // CUDA lets us use various std math functions on the device side.  This file
200b57cec5SDimitry Andric // works in concert with __clang_cuda_math_forward_declares.h to make this work.
210b57cec5SDimitry Andric //
220b57cec5SDimitry Andric // Specifically, the forward-declares header declares __device__ overloads for
230b57cec5SDimitry Andric // these functions in the global namespace, then pulls them into namespace std
240b57cec5SDimitry Andric // with 'using' statements.  Then this file implements those functions, after
250b57cec5SDimitry Andric // their implementations have been pulled in.
260b57cec5SDimitry Andric //
270b57cec5SDimitry Andric // It's important that we declare the functions in the global namespace and pull
280b57cec5SDimitry Andric // them into namespace std with using statements, as opposed to simply declaring
290b57cec5SDimitry Andric // these functions in namespace std, because our device functions need to
300b57cec5SDimitry Andric // overload the standard library functions, which may be declared in the global
310b57cec5SDimitry Andric // namespace or in std, depending on the degree of conformance of the stdlib
320b57cec5SDimitry Andric // implementation.  Declaring in the global namespace and pulling into namespace
330b57cec5SDimitry Andric // std covers all of the known knowns.
340b57cec5SDimitry Andric 
355ffd83dbSDimitry Andric #ifdef __OPENMP_NVPTX__
365ffd83dbSDimitry Andric #define __DEVICE__ static constexpr __attribute__((always_inline, nothrow))
370b57cec5SDimitry Andric #else
380b57cec5SDimitry Andric #define __DEVICE__ static __device__ __inline__ __attribute__((always_inline))
390b57cec5SDimitry Andric #endif
400b57cec5SDimitry Andric 
abs(long long __n)410b57cec5SDimitry Andric __DEVICE__ long long abs(long long __n) { return ::llabs(__n); }
abs(long __n)420b57cec5SDimitry Andric __DEVICE__ long abs(long __n) { return ::labs(__n); }
abs(float __x)430b57cec5SDimitry Andric __DEVICE__ float abs(float __x) { return ::fabsf(__x); }
abs(double __x)440b57cec5SDimitry Andric __DEVICE__ double abs(double __x) { return ::fabs(__x); }
acos(float __x)450b57cec5SDimitry Andric __DEVICE__ float acos(float __x) { return ::acosf(__x); }
asin(float __x)460b57cec5SDimitry Andric __DEVICE__ float asin(float __x) { return ::asinf(__x); }
atan(float __x)470b57cec5SDimitry Andric __DEVICE__ float atan(float __x) { return ::atanf(__x); }
atan2(float __x,float __y)480b57cec5SDimitry Andric __DEVICE__ float atan2(float __x, float __y) { return ::atan2f(__x, __y); }
ceil(float __x)490b57cec5SDimitry Andric __DEVICE__ float ceil(float __x) { return ::ceilf(__x); }
cos(float __x)500b57cec5SDimitry Andric __DEVICE__ float cos(float __x) { return ::cosf(__x); }
cosh(float __x)510b57cec5SDimitry Andric __DEVICE__ float cosh(float __x) { return ::coshf(__x); }
exp(float __x)520b57cec5SDimitry Andric __DEVICE__ float exp(float __x) { return ::expf(__x); }
fabs(float __x)535ffd83dbSDimitry Andric __DEVICE__ float fabs(float __x) { return ::fabsf(__x); }
floor(float __x)540b57cec5SDimitry Andric __DEVICE__ float floor(float __x) { return ::floorf(__x); }
fmod(float __x,float __y)550b57cec5SDimitry Andric __DEVICE__ float fmod(float __x, float __y) { return ::fmodf(__x, __y); }
fpclassify(float __x)560b57cec5SDimitry Andric __DEVICE__ int fpclassify(float __x) {
570b57cec5SDimitry Andric   return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL,
580b57cec5SDimitry Andric                               FP_ZERO, __x);
590b57cec5SDimitry Andric }
fpclassify(double __x)600b57cec5SDimitry Andric __DEVICE__ int fpclassify(double __x) {
610b57cec5SDimitry Andric   return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL,
620b57cec5SDimitry Andric                               FP_ZERO, __x);
630b57cec5SDimitry Andric }
frexp(float __arg,int * __exp)640b57cec5SDimitry Andric __DEVICE__ float frexp(float __arg, int *__exp) {
650b57cec5SDimitry Andric   return ::frexpf(__arg, __exp);
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric // For inscrutable reasons, the CUDA headers define these functions for us on
69*e8d8bef9SDimitry Andric // Windows.
70*e8d8bef9SDimitry Andric #if !defined(_MSC_VER) || defined(__OPENMP_NVPTX__)
71*e8d8bef9SDimitry Andric 
72*e8d8bef9SDimitry Andric // For OpenMP we work around some old system headers that have non-conforming
73*e8d8bef9SDimitry Andric // `isinf(float)` and `isnan(float)` implementations that return an `int`. We do
74*e8d8bef9SDimitry Andric // this by providing two versions of these functions, differing only in the
75*e8d8bef9SDimitry Andric // return type. To avoid conflicting definitions we disable implicit base
76*e8d8bef9SDimitry Andric // function generation. That means we will end up with two specializations, one
77*e8d8bef9SDimitry Andric // per type, but only one has a base function defined by the system header.
78*e8d8bef9SDimitry Andric #if defined(__OPENMP_NVPTX__)
79*e8d8bef9SDimitry Andric #pragma omp begin declare variant match(                                       \
80*e8d8bef9SDimitry Andric     implementation = {extension(disable_implicit_base)})
81*e8d8bef9SDimitry Andric 
82*e8d8bef9SDimitry Andric // FIXME: We lack an extension to customize the mangling of the variants, e.g.,
83*e8d8bef9SDimitry Andric //        add a suffix. This means we would clash with the names of the variants
84*e8d8bef9SDimitry Andric //        (note that we do not create implicit base functions here). To avoid
85*e8d8bef9SDimitry Andric //        this clash we add a new trait to some of them that is always true
86*e8d8bef9SDimitry Andric //        (this is LLVM after all ;)). It will only influence the mangled name
87*e8d8bef9SDimitry Andric //        of the variants inside the inner region and avoid the clash.
88*e8d8bef9SDimitry Andric #pragma omp begin declare variant match(implementation = {vendor(llvm)})
89*e8d8bef9SDimitry Andric 
isinf(float __x)90*e8d8bef9SDimitry Andric __DEVICE__ int isinf(float __x) { return ::__isinff(__x); }
isinf(double __x)91*e8d8bef9SDimitry Andric __DEVICE__ int isinf(double __x) { return ::__isinf(__x); }
isfinite(float __x)92*e8d8bef9SDimitry Andric __DEVICE__ int isfinite(float __x) { return ::__finitef(__x); }
isfinite(double __x)93*e8d8bef9SDimitry Andric __DEVICE__ int isfinite(double __x) { return ::__isfinited(__x); }
isnan(float __x)94*e8d8bef9SDimitry Andric __DEVICE__ int isnan(float __x) { return ::__isnanf(__x); }
isnan(double __x)95*e8d8bef9SDimitry Andric __DEVICE__ int isnan(double __x) { return ::__isnan(__x); }
96*e8d8bef9SDimitry Andric 
97*e8d8bef9SDimitry Andric #pragma omp end declare variant
98*e8d8bef9SDimitry Andric 
99*e8d8bef9SDimitry Andric #endif
100*e8d8bef9SDimitry Andric 
isinf(float __x)1010b57cec5SDimitry Andric __DEVICE__ bool isinf(float __x) { return ::__isinff(__x); }
isinf(double __x)1020b57cec5SDimitry Andric __DEVICE__ bool isinf(double __x) { return ::__isinf(__x); }
isfinite(float __x)1030b57cec5SDimitry Andric __DEVICE__ bool isfinite(float __x) { return ::__finitef(__x); }
1040b57cec5SDimitry Andric // For inscrutable reasons, __finite(), the double-precision version of
1050b57cec5SDimitry Andric // __finitef, does not exist when compiling for MacOS.  __isfinited is available
1060b57cec5SDimitry Andric // everywhere and is just as good.
isfinite(double __x)1070b57cec5SDimitry Andric __DEVICE__ bool isfinite(double __x) { return ::__isfinited(__x); }
isnan(float __x)1080b57cec5SDimitry Andric __DEVICE__ bool isnan(float __x) { return ::__isnanf(__x); }
isnan(double __x)1090b57cec5SDimitry Andric __DEVICE__ bool isnan(double __x) { return ::__isnan(__x); }
110*e8d8bef9SDimitry Andric 
111*e8d8bef9SDimitry Andric #if defined(__OPENMP_NVPTX__)
112*e8d8bef9SDimitry Andric #pragma omp end declare variant
113*e8d8bef9SDimitry Andric #endif
114*e8d8bef9SDimitry Andric 
1150b57cec5SDimitry Andric #endif
1160b57cec5SDimitry Andric 
isgreater(float __x,float __y)1170b57cec5SDimitry Andric __DEVICE__ bool isgreater(float __x, float __y) {
1180b57cec5SDimitry Andric   return __builtin_isgreater(__x, __y);
1190b57cec5SDimitry Andric }
isgreater(double __x,double __y)1200b57cec5SDimitry Andric __DEVICE__ bool isgreater(double __x, double __y) {
1210b57cec5SDimitry Andric   return __builtin_isgreater(__x, __y);
1220b57cec5SDimitry Andric }
isgreaterequal(float __x,float __y)1230b57cec5SDimitry Andric __DEVICE__ bool isgreaterequal(float __x, float __y) {
1240b57cec5SDimitry Andric   return __builtin_isgreaterequal(__x, __y);
1250b57cec5SDimitry Andric }
isgreaterequal(double __x,double __y)1260b57cec5SDimitry Andric __DEVICE__ bool isgreaterequal(double __x, double __y) {
1270b57cec5SDimitry Andric   return __builtin_isgreaterequal(__x, __y);
1280b57cec5SDimitry Andric }
isless(float __x,float __y)1290b57cec5SDimitry Andric __DEVICE__ bool isless(float __x, float __y) {
1300b57cec5SDimitry Andric   return __builtin_isless(__x, __y);
1310b57cec5SDimitry Andric }
isless(double __x,double __y)1320b57cec5SDimitry Andric __DEVICE__ bool isless(double __x, double __y) {
1330b57cec5SDimitry Andric   return __builtin_isless(__x, __y);
1340b57cec5SDimitry Andric }
islessequal(float __x,float __y)1350b57cec5SDimitry Andric __DEVICE__ bool islessequal(float __x, float __y) {
1360b57cec5SDimitry Andric   return __builtin_islessequal(__x, __y);
1370b57cec5SDimitry Andric }
islessequal(double __x,double __y)1380b57cec5SDimitry Andric __DEVICE__ bool islessequal(double __x, double __y) {
1390b57cec5SDimitry Andric   return __builtin_islessequal(__x, __y);
1400b57cec5SDimitry Andric }
islessgreater(float __x,float __y)1410b57cec5SDimitry Andric __DEVICE__ bool islessgreater(float __x, float __y) {
1420b57cec5SDimitry Andric   return __builtin_islessgreater(__x, __y);
1430b57cec5SDimitry Andric }
islessgreater(double __x,double __y)1440b57cec5SDimitry Andric __DEVICE__ bool islessgreater(double __x, double __y) {
1450b57cec5SDimitry Andric   return __builtin_islessgreater(__x, __y);
1460b57cec5SDimitry Andric }
isnormal(float __x)1470b57cec5SDimitry Andric __DEVICE__ bool isnormal(float __x) { return __builtin_isnormal(__x); }
isnormal(double __x)1480b57cec5SDimitry Andric __DEVICE__ bool isnormal(double __x) { return __builtin_isnormal(__x); }
isunordered(float __x,float __y)1490b57cec5SDimitry Andric __DEVICE__ bool isunordered(float __x, float __y) {
1500b57cec5SDimitry Andric   return __builtin_isunordered(__x, __y);
1510b57cec5SDimitry Andric }
isunordered(double __x,double __y)1520b57cec5SDimitry Andric __DEVICE__ bool isunordered(double __x, double __y) {
1530b57cec5SDimitry Andric   return __builtin_isunordered(__x, __y);
1540b57cec5SDimitry Andric }
ldexp(float __arg,int __exp)1550b57cec5SDimitry Andric __DEVICE__ float ldexp(float __arg, int __exp) {
1560b57cec5SDimitry Andric   return ::ldexpf(__arg, __exp);
1570b57cec5SDimitry Andric }
log(float __x)1580b57cec5SDimitry Andric __DEVICE__ float log(float __x) { return ::logf(__x); }
log10(float __x)1590b57cec5SDimitry Andric __DEVICE__ float log10(float __x) { return ::log10f(__x); }
modf(float __x,float * __iptr)1600b57cec5SDimitry Andric __DEVICE__ float modf(float __x, float *__iptr) { return ::modff(__x, __iptr); }
pow(float __base,float __exp)1610b57cec5SDimitry Andric __DEVICE__ float pow(float __base, float __exp) {
1620b57cec5SDimitry Andric   return ::powf(__base, __exp);
1630b57cec5SDimitry Andric }
pow(float __base,int __iexp)1640b57cec5SDimitry Andric __DEVICE__ float pow(float __base, int __iexp) {
1650b57cec5SDimitry Andric   return ::powif(__base, __iexp);
1660b57cec5SDimitry Andric }
pow(double __base,int __iexp)1670b57cec5SDimitry Andric __DEVICE__ double pow(double __base, int __iexp) {
1680b57cec5SDimitry Andric   return ::powi(__base, __iexp);
1690b57cec5SDimitry Andric }
signbit(float __x)1700b57cec5SDimitry Andric __DEVICE__ bool signbit(float __x) { return ::__signbitf(__x); }
signbit(double __x)1710b57cec5SDimitry Andric __DEVICE__ bool signbit(double __x) { return ::__signbitd(__x); }
sin(float __x)1720b57cec5SDimitry Andric __DEVICE__ float sin(float __x) { return ::sinf(__x); }
sinh(float __x)1730b57cec5SDimitry Andric __DEVICE__ float sinh(float __x) { return ::sinhf(__x); }
sqrt(float __x)1740b57cec5SDimitry Andric __DEVICE__ float sqrt(float __x) { return ::sqrtf(__x); }
tan(float __x)1750b57cec5SDimitry Andric __DEVICE__ float tan(float __x) { return ::tanf(__x); }
tanh(float __x)1760b57cec5SDimitry Andric __DEVICE__ float tanh(float __x) { return ::tanhf(__x); }
1770b57cec5SDimitry Andric 
178*e8d8bef9SDimitry Andric // There was a redefinition error for this this overload in CUDA mode.
179*e8d8bef9SDimitry Andric // We restrict it to OpenMP mode for now, that is where it is actually needed
180*e8d8bef9SDimitry Andric // anyway.
181*e8d8bef9SDimitry Andric #ifdef __OPENMP_NVPTX__
remquo(float __n,float __d,int * __q)182*e8d8bef9SDimitry Andric __DEVICE__ float remquo(float __n, float __d, int *__q) {
183*e8d8bef9SDimitry Andric   return ::remquof(__n, __d, __q);
184*e8d8bef9SDimitry Andric }
185*e8d8bef9SDimitry Andric #endif
186*e8d8bef9SDimitry Andric 
1870b57cec5SDimitry Andric // Notably missing above is nexttoward.  We omit it because
1880b57cec5SDimitry Andric // libdevice doesn't provide an implementation, and we don't want to be in the
1890b57cec5SDimitry Andric // business of implementing tricky libm functions in this header.
1900b57cec5SDimitry Andric 
1915ffd83dbSDimitry Andric #ifndef __OPENMP_NVPTX__
1925ffd83dbSDimitry Andric 
1930b57cec5SDimitry Andric // Now we've defined everything we promised we'd define in
1940b57cec5SDimitry Andric // __clang_cuda_math_forward_declares.h.  We need to do two additional things to
1950b57cec5SDimitry Andric // fix up our math functions.
1960b57cec5SDimitry Andric //
1970b57cec5SDimitry Andric // 1) Define __device__ overloads for e.g. sin(int).  The CUDA headers define
1980b57cec5SDimitry Andric //    only sin(float) and sin(double), which means that e.g. sin(0) is
1990b57cec5SDimitry Andric //    ambiguous.
2000b57cec5SDimitry Andric //
2010b57cec5SDimitry Andric // 2) Pull the __device__ overloads of "foobarf" math functions into namespace
2020b57cec5SDimitry Andric //    std.  These are defined in the CUDA headers in the global namespace,
2030b57cec5SDimitry Andric //    independent of everything else we've done here.
2040b57cec5SDimitry Andric 
2050b57cec5SDimitry Andric // We can't use std::enable_if, because we want to be pre-C++11 compatible.  But
2060b57cec5SDimitry Andric // we go ahead and unconditionally define functions that are only available when
2070b57cec5SDimitry Andric // compiling for C++11 to match the behavior of the CUDA headers.
2080b57cec5SDimitry Andric template<bool __B, class __T = void>
2090b57cec5SDimitry Andric struct __clang_cuda_enable_if {};
2100b57cec5SDimitry Andric 
2110b57cec5SDimitry Andric template <class __T> struct __clang_cuda_enable_if<true, __T> {
2120b57cec5SDimitry Andric   typedef __T type;
2130b57cec5SDimitry Andric };
2140b57cec5SDimitry Andric 
2150b57cec5SDimitry Andric // Defines an overload of __fn that accepts one integral argument, calls
2160b57cec5SDimitry Andric // __fn((double)x), and returns __retty.
2170b57cec5SDimitry Andric #define __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(__retty, __fn)                      \
2180b57cec5SDimitry Andric   template <typename __T>                                                      \
2190b57cec5SDimitry Andric   __DEVICE__                                                                   \
2200b57cec5SDimitry Andric       typename __clang_cuda_enable_if<std::numeric_limits<__T>::is_integer,    \
2210b57cec5SDimitry Andric                                       __retty>::type                           \
2220b57cec5SDimitry Andric       __fn(__T __x) {                                                          \
2230b57cec5SDimitry Andric     return ::__fn((double)__x);                                                \
2240b57cec5SDimitry Andric   }
2250b57cec5SDimitry Andric 
2260b57cec5SDimitry Andric // Defines an overload of __fn that accepts one two arithmetic arguments, calls
2270b57cec5SDimitry Andric // __fn((double)x, (double)y), and returns a double.
2280b57cec5SDimitry Andric //
2290b57cec5SDimitry Andric // Note this is different from OVERLOAD_1, which generates an overload that
2300b57cec5SDimitry Andric // accepts only *integral* arguments.
2310b57cec5SDimitry Andric #define __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(__retty, __fn)                      \
2320b57cec5SDimitry Andric   template <typename __T1, typename __T2>                                      \
2330b57cec5SDimitry Andric   __DEVICE__ typename __clang_cuda_enable_if<                                  \
2340b57cec5SDimitry Andric       std::numeric_limits<__T1>::is_specialized &&                             \
2350b57cec5SDimitry Andric           std::numeric_limits<__T2>::is_specialized,                           \
2360b57cec5SDimitry Andric       __retty>::type                                                           \
2370b57cec5SDimitry Andric   __fn(__T1 __x, __T2 __y) {                                                   \
2380b57cec5SDimitry Andric     return __fn((double)__x, (double)__y);                                     \
2390b57cec5SDimitry Andric   }
2400b57cec5SDimitry Andric 
2410b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, acos)
2420b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, acosh)
2430b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, asin)
2440b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, asinh)
2450b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, atan)
2460b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, atan2);
2470b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, atanh)
2480b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, cbrt)
2490b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, ceil)
2500b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, copysign);
2510b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, cos)
2520b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, cosh)
2530b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, erf)
2540b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, erfc)
2550b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, exp)
2560b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, exp2)
2570b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, expm1)
2580b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, fabs)
2590b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, fdim);
2600b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, floor)
2610b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, fmax);
2620b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, fmin);
2630b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, fmod);
2640b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(int, fpclassify)
2650b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, hypot);
2660b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(int, ilogb)
2670b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(bool, isfinite)
2680b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(bool, isgreater);
2690b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(bool, isgreaterequal);
2700b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(bool, isinf);
2710b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(bool, isless);
2720b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(bool, islessequal);
2730b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(bool, islessgreater);
2740b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(bool, isnan);
2750b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(bool, isnormal)
2760b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(bool, isunordered);
2770b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, lgamma)
2780b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, log)
2790b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, log10)
2800b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, log1p)
2810b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, log2)
2820b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, logb)
2830b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(long long, llrint)
2840b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(long long, llround)
2850b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(long, lrint)
2860b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(long, lround)
2870b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, nearbyint);
2880b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, nextafter);
2890b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, pow);
2900b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, remainder);
2910b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, rint);
2920b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, round);
2930b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(bool, signbit)
2940b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, sin)
2950b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, sinh)
2960b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, sqrt)
2970b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, tan)
2980b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, tanh)
2990b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, tgamma)
3000b57cec5SDimitry Andric __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, trunc);
3010b57cec5SDimitry Andric 
3020b57cec5SDimitry Andric #undef __CUDA_CLANG_FN_INTEGER_OVERLOAD_1
3030b57cec5SDimitry Andric #undef __CUDA_CLANG_FN_INTEGER_OVERLOAD_2
3040b57cec5SDimitry Andric 
3050b57cec5SDimitry Andric // Overloads for functions that don't match the patterns expected by
3060b57cec5SDimitry Andric // __CUDA_CLANG_FN_INTEGER_OVERLOAD_{1,2}.
3070b57cec5SDimitry Andric template <typename __T1, typename __T2, typename __T3>
3080b57cec5SDimitry Andric __DEVICE__ typename __clang_cuda_enable_if<
3090b57cec5SDimitry Andric     std::numeric_limits<__T1>::is_specialized &&
3100b57cec5SDimitry Andric         std::numeric_limits<__T2>::is_specialized &&
3110b57cec5SDimitry Andric         std::numeric_limits<__T3>::is_specialized,
3120b57cec5SDimitry Andric     double>::type
3130b57cec5SDimitry Andric fma(__T1 __x, __T2 __y, __T3 __z) {
3140b57cec5SDimitry Andric   return std::fma((double)__x, (double)__y, (double)__z);
3150b57cec5SDimitry Andric }
3160b57cec5SDimitry Andric 
3170b57cec5SDimitry Andric template <typename __T>
3180b57cec5SDimitry Andric __DEVICE__ typename __clang_cuda_enable_if<std::numeric_limits<__T>::is_integer,
3190b57cec5SDimitry Andric                                            double>::type
3200b57cec5SDimitry Andric frexp(__T __x, int *__exp) {
3210b57cec5SDimitry Andric   return std::frexp((double)__x, __exp);
3220b57cec5SDimitry Andric }
3230b57cec5SDimitry Andric 
3240b57cec5SDimitry Andric template <typename __T>
3250b57cec5SDimitry Andric __DEVICE__ typename __clang_cuda_enable_if<std::numeric_limits<__T>::is_integer,
3260b57cec5SDimitry Andric                                            double>::type
3270b57cec5SDimitry Andric ldexp(__T __x, int __exp) {
3280b57cec5SDimitry Andric   return std::ldexp((double)__x, __exp);
3290b57cec5SDimitry Andric }
3300b57cec5SDimitry Andric 
3310b57cec5SDimitry Andric template <typename __T1, typename __T2>
3320b57cec5SDimitry Andric __DEVICE__ typename __clang_cuda_enable_if<
3330b57cec5SDimitry Andric     std::numeric_limits<__T1>::is_specialized &&
3340b57cec5SDimitry Andric         std::numeric_limits<__T2>::is_specialized,
3350b57cec5SDimitry Andric     double>::type
3360b57cec5SDimitry Andric remquo(__T1 __x, __T2 __y, int *__quo) {
3370b57cec5SDimitry Andric   return std::remquo((double)__x, (double)__y, __quo);
3380b57cec5SDimitry Andric }
3390b57cec5SDimitry Andric 
3400b57cec5SDimitry Andric template <typename __T>
3410b57cec5SDimitry Andric __DEVICE__ typename __clang_cuda_enable_if<std::numeric_limits<__T>::is_integer,
3420b57cec5SDimitry Andric                                            double>::type
3430b57cec5SDimitry Andric scalbln(__T __x, long __exp) {
3440b57cec5SDimitry Andric   return std::scalbln((double)__x, __exp);
3450b57cec5SDimitry Andric }
3460b57cec5SDimitry Andric 
3470b57cec5SDimitry Andric template <typename __T>
3480b57cec5SDimitry Andric __DEVICE__ typename __clang_cuda_enable_if<std::numeric_limits<__T>::is_integer,
3490b57cec5SDimitry Andric                                            double>::type
3500b57cec5SDimitry Andric scalbn(__T __x, int __exp) {
3510b57cec5SDimitry Andric   return std::scalbn((double)__x, __exp);
3520b57cec5SDimitry Andric }
3530b57cec5SDimitry Andric 
3540b57cec5SDimitry Andric // We need to define these overloads in exactly the namespace our standard
3550b57cec5SDimitry Andric // library uses (including the right inline namespace), otherwise they won't be
3560b57cec5SDimitry Andric // picked up by other functions in the standard library (e.g. functions in
3570b57cec5SDimitry Andric // <complex>).  Thus the ugliness below.
3580b57cec5SDimitry Andric #ifdef _LIBCPP_BEGIN_NAMESPACE_STD
3590b57cec5SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
3600b57cec5SDimitry Andric #else
3610b57cec5SDimitry Andric namespace std {
3620b57cec5SDimitry Andric #ifdef _GLIBCXX_BEGIN_NAMESPACE_VERSION
3630b57cec5SDimitry Andric _GLIBCXX_BEGIN_NAMESPACE_VERSION
3640b57cec5SDimitry Andric #endif
3650b57cec5SDimitry Andric #endif
3660b57cec5SDimitry Andric 
3670b57cec5SDimitry Andric // Pull the new overloads we defined above into namespace std.
3680b57cec5SDimitry Andric using ::acos;
3690b57cec5SDimitry Andric using ::acosh;
3700b57cec5SDimitry Andric using ::asin;
3710b57cec5SDimitry Andric using ::asinh;
3720b57cec5SDimitry Andric using ::atan;
3730b57cec5SDimitry Andric using ::atan2;
3740b57cec5SDimitry Andric using ::atanh;
3750b57cec5SDimitry Andric using ::cbrt;
3760b57cec5SDimitry Andric using ::ceil;
3770b57cec5SDimitry Andric using ::copysign;
3780b57cec5SDimitry Andric using ::cos;
3790b57cec5SDimitry Andric using ::cosh;
3800b57cec5SDimitry Andric using ::erf;
3810b57cec5SDimitry Andric using ::erfc;
3820b57cec5SDimitry Andric using ::exp;
3830b57cec5SDimitry Andric using ::exp2;
3840b57cec5SDimitry Andric using ::expm1;
3850b57cec5SDimitry Andric using ::fabs;
3860b57cec5SDimitry Andric using ::fdim;
3870b57cec5SDimitry Andric using ::floor;
3880b57cec5SDimitry Andric using ::fma;
3890b57cec5SDimitry Andric using ::fmax;
3900b57cec5SDimitry Andric using ::fmin;
3910b57cec5SDimitry Andric using ::fmod;
3920b57cec5SDimitry Andric using ::fpclassify;
3930b57cec5SDimitry Andric using ::frexp;
3940b57cec5SDimitry Andric using ::hypot;
3950b57cec5SDimitry Andric using ::ilogb;
3960b57cec5SDimitry Andric using ::isfinite;
3970b57cec5SDimitry Andric using ::isgreater;
3980b57cec5SDimitry Andric using ::isgreaterequal;
3990b57cec5SDimitry Andric using ::isless;
4000b57cec5SDimitry Andric using ::islessequal;
4010b57cec5SDimitry Andric using ::islessgreater;
4020b57cec5SDimitry Andric using ::isnormal;
4030b57cec5SDimitry Andric using ::isunordered;
4040b57cec5SDimitry Andric using ::ldexp;
4050b57cec5SDimitry Andric using ::lgamma;
4060b57cec5SDimitry Andric using ::llrint;
4070b57cec5SDimitry Andric using ::llround;
4080b57cec5SDimitry Andric using ::log;
4090b57cec5SDimitry Andric using ::log10;
4100b57cec5SDimitry Andric using ::log1p;
4110b57cec5SDimitry Andric using ::log2;
4120b57cec5SDimitry Andric using ::logb;
4130b57cec5SDimitry Andric using ::lrint;
4140b57cec5SDimitry Andric using ::lround;
4150b57cec5SDimitry Andric using ::nearbyint;
4160b57cec5SDimitry Andric using ::nextafter;
4170b57cec5SDimitry Andric using ::pow;
4180b57cec5SDimitry Andric using ::remainder;
4190b57cec5SDimitry Andric using ::remquo;
4200b57cec5SDimitry Andric using ::rint;
4210b57cec5SDimitry Andric using ::round;
4220b57cec5SDimitry Andric using ::scalbln;
4230b57cec5SDimitry Andric using ::scalbn;
4240b57cec5SDimitry Andric using ::signbit;
4250b57cec5SDimitry Andric using ::sin;
4260b57cec5SDimitry Andric using ::sinh;
4270b57cec5SDimitry Andric using ::sqrt;
4280b57cec5SDimitry Andric using ::tan;
4290b57cec5SDimitry Andric using ::tanh;
4300b57cec5SDimitry Andric using ::tgamma;
4310b57cec5SDimitry Andric using ::trunc;
4320b57cec5SDimitry Andric 
4330b57cec5SDimitry Andric // Well this is fun: We need to pull these symbols in for libc++, but we can't
4340b57cec5SDimitry Andric // pull them in with libstdc++, because its ::isinf and ::isnan are different
4350b57cec5SDimitry Andric // than its std::isinf and std::isnan.
4360b57cec5SDimitry Andric #ifndef __GLIBCXX__
4370b57cec5SDimitry Andric using ::isinf;
4380b57cec5SDimitry Andric using ::isnan;
4390b57cec5SDimitry Andric #endif
4400b57cec5SDimitry Andric 
4410b57cec5SDimitry Andric // Finally, pull the "foobarf" functions that CUDA defines in its headers into
4420b57cec5SDimitry Andric // namespace std.
4430b57cec5SDimitry Andric using ::acosf;
4440b57cec5SDimitry Andric using ::acoshf;
4450b57cec5SDimitry Andric using ::asinf;
4460b57cec5SDimitry Andric using ::asinhf;
4470b57cec5SDimitry Andric using ::atan2f;
4480b57cec5SDimitry Andric using ::atanf;
4490b57cec5SDimitry Andric using ::atanhf;
4500b57cec5SDimitry Andric using ::cbrtf;
4510b57cec5SDimitry Andric using ::ceilf;
4520b57cec5SDimitry Andric using ::copysignf;
4530b57cec5SDimitry Andric using ::cosf;
4540b57cec5SDimitry Andric using ::coshf;
4550b57cec5SDimitry Andric using ::erfcf;
4560b57cec5SDimitry Andric using ::erff;
4570b57cec5SDimitry Andric using ::exp2f;
4580b57cec5SDimitry Andric using ::expf;
4590b57cec5SDimitry Andric using ::expm1f;
4600b57cec5SDimitry Andric using ::fabsf;
4610b57cec5SDimitry Andric using ::fdimf;
4620b57cec5SDimitry Andric using ::floorf;
4630b57cec5SDimitry Andric using ::fmaf;
4640b57cec5SDimitry Andric using ::fmaxf;
4650b57cec5SDimitry Andric using ::fminf;
4660b57cec5SDimitry Andric using ::fmodf;
4670b57cec5SDimitry Andric using ::frexpf;
4680b57cec5SDimitry Andric using ::hypotf;
4690b57cec5SDimitry Andric using ::ilogbf;
4700b57cec5SDimitry Andric using ::ldexpf;
4710b57cec5SDimitry Andric using ::lgammaf;
4720b57cec5SDimitry Andric using ::llrintf;
4730b57cec5SDimitry Andric using ::llroundf;
4740b57cec5SDimitry Andric using ::log10f;
4750b57cec5SDimitry Andric using ::log1pf;
4760b57cec5SDimitry Andric using ::log2f;
4770b57cec5SDimitry Andric using ::logbf;
4780b57cec5SDimitry Andric using ::logf;
4790b57cec5SDimitry Andric using ::lrintf;
4800b57cec5SDimitry Andric using ::lroundf;
4810b57cec5SDimitry Andric using ::modff;
4820b57cec5SDimitry Andric using ::nearbyintf;
4830b57cec5SDimitry Andric using ::nextafterf;
4840b57cec5SDimitry Andric using ::powf;
4850b57cec5SDimitry Andric using ::remainderf;
4860b57cec5SDimitry Andric using ::remquof;
4870b57cec5SDimitry Andric using ::rintf;
4880b57cec5SDimitry Andric using ::roundf;
4890b57cec5SDimitry Andric using ::scalblnf;
4900b57cec5SDimitry Andric using ::scalbnf;
4910b57cec5SDimitry Andric using ::sinf;
4920b57cec5SDimitry Andric using ::sinhf;
4930b57cec5SDimitry Andric using ::sqrtf;
4940b57cec5SDimitry Andric using ::tanf;
4950b57cec5SDimitry Andric using ::tanhf;
4960b57cec5SDimitry Andric using ::tgammaf;
4970b57cec5SDimitry Andric using ::truncf;
4980b57cec5SDimitry Andric 
4990b57cec5SDimitry Andric #ifdef _LIBCPP_END_NAMESPACE_STD
5000b57cec5SDimitry Andric _LIBCPP_END_NAMESPACE_STD
5010b57cec5SDimitry Andric #else
5020b57cec5SDimitry Andric #ifdef _GLIBCXX_BEGIN_NAMESPACE_VERSION
5030b57cec5SDimitry Andric _GLIBCXX_END_NAMESPACE_VERSION
5040b57cec5SDimitry Andric #endif
5050b57cec5SDimitry Andric } // namespace std
5060b57cec5SDimitry Andric #endif
5070b57cec5SDimitry Andric 
5085ffd83dbSDimitry Andric #endif // __OPENMP_NVPTX__
5095ffd83dbSDimitry Andric 
5100b57cec5SDimitry Andric #undef __DEVICE__
5110b57cec5SDimitry Andric 
5120b57cec5SDimitry Andric #endif
513