diff --git a/libdevice/cmath_wrapper.cpp b/libdevice/cmath_wrapper.cpp index 321092a3720b0..b3f0373db90c7 100644 --- a/libdevice/cmath_wrapper.cpp +++ b/libdevice/cmath_wrapper.cpp @@ -181,6 +181,47 @@ short _FDtest(float *px) { // categorize *px return ret; } +// Returns _FP_LT, _FP_GT or _FP_EQ based on the ordering +// relationship between x and y. '0' means unordered. +DEVICE_EXTERN_C +int _fdpcomp(float x, float y) { + int res = 0; + if (_FDtest(&x) == _NANCODE || _FDtest(&y) == _NANCODE) { + // '0' means unordered. + return res; + } + + if (x < y) + res |= _FP_LT; + else if (x > y) + res |= _FP_GT; + else + res |= _FP_EQ; + + return res; +} + +// Returns 0, if the sign bit is not set, and non-zero otherwise. +DEVICE_EXTERN_C +int _fdsign(float x) { return FSIGN(x); } + +// fpclassify() equivalent with a pointer argument. +DEVICE_EXTERN_C +short _fdtest(float *px) { + switch (_FDtest(px)) { + case _DENORM: + return FP_SUBNORMAL; + case _FINITE: + return FP_NORMAL; + case _INFCODE: + return FP_INFINITE; + case _NANCODE: + return FP_NAN; + } + + return FP_ZERO; +} + DEVICE_EXTERN_C short _FDnorm(_Fval *ps) { // normalize float fraction short xchar; diff --git a/libdevice/cmath_wrapper_fp64.cpp b/libdevice/cmath_wrapper_fp64.cpp index f6e55a6e30a4d..25095d88a519b 100644 --- a/libdevice/cmath_wrapper_fp64.cpp +++ b/libdevice/cmath_wrapper_fp64.cpp @@ -133,6 +133,9 @@ double asinh(double x) { return __devicelib_asinh(x); } DEVICE_EXTERN_C double atanh(double x) { return __devicelib_atanh(x); } +DEVICE_EXTERN_C +double scalbn(double x, int exp) { return __devicelib_scalbn(x, exp); } + #if defined(_WIN32) #include // FLOAT PROPERTIES @@ -180,6 +183,47 @@ short _Dtest(double *px) { // categorize *px return ret; } +// Returns _FP_LT, _FP_GT or _FP_EQ based on the ordering +// relationship between x and y. +DEVICE_EXTERN_C +int _dpcomp(double x, double y) { + int res = 0; + if (_Dtest(&x) == _NANCODE || _Dtest(&y) == _NANCODE) { + // '0' means unordered. + return res; + } + + if (x < y) + res |= _FP_LT; + else if (x > y) + res |= _FP_GT; + else + res |= _FP_EQ; + + return res; +} + +// Returns 0, if the sign bit is not set, and non-zero otherwise. +DEVICE_EXTERN_C +int _dsign(double x) { return DSIGN(x); } + +// fpclassify() equivalent with a pointer argument. +DEVICE_EXTERN_C +short _dtest(double *px) { + switch (_Dtest(px)) { + case _DENORM: + return FP_SUBNORMAL; + case _FINITE: + return FP_NORMAL; + case _INFCODE: + return FP_INFINITE; + case _NANCODE: + return FP_NAN; + } + + return FP_ZERO; +} + DEVICE_EXTERN_C short _Dnorm(_Dval *ps) { // normalize double fraction short xchar; diff --git a/libdevice/device_math.h b/libdevice/device_math.h index 5d15a80d73da3..e751bd3ad0278 100644 --- a/libdevice/device_math.h +++ b/libdevice/device_math.h @@ -249,5 +249,8 @@ float __devicelib_logbf(float x); DEVICE_EXTERN_C float __devicelib_scalbnf(float x, int n); + +DEVICE_EXTERN_C +double __devicelib_scalbn(double x, int exp); #endif // __SPIR__ #endif // __LIBDEVICE_DEVICE_MATH_H__ diff --git a/libdevice/fallback-cmath-fp64.cpp b/libdevice/fallback-cmath-fp64.cpp index a17b8b1eb16c0..8d032ffd1c18c 100644 --- a/libdevice/fallback-cmath-fp64.cpp +++ b/libdevice/fallback-cmath-fp64.cpp @@ -143,4 +143,9 @@ double __devicelib_asinh(double x) { return __spirv_ocl_asinh(x); } DEVICE_EXTERN_C double __devicelib_atanh(double x) { return __spirv_ocl_atanh(x); } + +DEVICE_EXTERN_C +double __devicelib_scalbn(double x, int exp) { + return __spirv_ocl_ldexp(x, exp); +} #endif // __SPIR__ diff --git a/llvm/tools/sycl-post-link/sycl-post-link.cpp b/llvm/tools/sycl-post-link/sycl-post-link.cpp index a7fa663e31f7d..e359ba494ddc0 100644 --- a/llvm/tools/sycl-post-link/sycl-post-link.cpp +++ b/llvm/tools/sycl-post-link/sycl-post-link.cpp @@ -167,6 +167,7 @@ static std::unordered_map DeviceLibFuncMap = { {"__devicelib_powf", DeviceLibExt::cl_intel_devicelib_math}, {"__devicelib_remainderf", DeviceLibExt::cl_intel_devicelib_math}, {"__devicelib_remquof", DeviceLibExt::cl_intel_devicelib_math}, + {"__devicelib_scalbnf", DeviceLibExt::cl_intel_devicelib_math}, {"__devicelib_sinf", DeviceLibExt::cl_intel_devicelib_math}, {"__devicelib_sinhf", DeviceLibExt::cl_intel_devicelib_math}, {"__devicelib_sqrtf", DeviceLibExt::cl_intel_devicelib_math}, @@ -206,6 +207,7 @@ static std::unordered_map DeviceLibFuncMap = { {"__devicelib_pow", DeviceLibExt::cl_intel_devicelib_math_fp64}, {"__devicelib_remainder", DeviceLibExt::cl_intel_devicelib_math_fp64}, {"__devicelib_remquo", DeviceLibExt::cl_intel_devicelib_math_fp64}, + {"__devicelib_scalbn", DeviceLibExt::cl_intel_devicelib_math_fp64}, {"__devicelib_sin", DeviceLibExt::cl_intel_devicelib_math_fp64}, {"__devicelib_sinh", DeviceLibExt::cl_intel_devicelib_math_fp64}, {"__devicelib_sqrt", DeviceLibExt::cl_intel_devicelib_math_fp64}, diff --git a/sycl/include/CL/sycl/builtins.hpp b/sycl/include/CL/sycl/builtins.hpp index 9671987643f41..4f3a850db592b 100644 --- a/sycl/include/CL/sycl/builtins.hpp +++ b/sycl/include/CL/sycl/builtins.hpp @@ -1551,11 +1551,23 @@ extern SYCL_EXTERNAL void __assert_fail(const char *expr, const char *file, } #elif defined(_WIN32) extern "C" { +// TODO: documented C runtime library APIs must be recognized as +// builtins by FE. This includes _dpcomp, _dsign, _dtest, +// _fdpcomp, _fdsign, _fdtest, _hypotf, _wassert. +// APIs used by STL, such as _Cosh, are undocumented, even though +// they are open-sourced. Recognizing them as builtins is not +// straightforward currently. extern SYCL_EXTERNAL double _Cosh(double x, double y); +extern SYCL_EXTERNAL int _dpcomp(double x, double y); +extern SYCL_EXTERNAL int _dsign(double x); extern SYCL_EXTERNAL short _Dtest(double *px); +extern SYCL_EXTERNAL short _dtest(double *px); extern SYCL_EXTERNAL short _Exp(double *px, double y, short eoff); extern SYCL_EXTERNAL float _FCosh(float x, float y); +extern SYCL_EXTERNAL int _fdpcomp(float x, float y); +extern SYCL_EXTERNAL int _fdsign(float x); extern SYCL_EXTERNAL short _FDtest(float *px); +extern SYCL_EXTERNAL short _fdtest(float *px); extern SYCL_EXTERNAL short _FExp(float *px, float y, short eoff); extern SYCL_EXTERNAL float _FSinh(float x, float y); extern SYCL_EXTERNAL double _Sinh(double x, double y); diff --git a/sycl/test/devicelib/cmath_fp64_test.cpp b/sycl/test/devicelib/cmath_fp64_test.cpp index d1f42613c6c5f..5c77bcda5a64e 100644 --- a/sycl/test/devicelib/cmath_fp64_test.cpp +++ b/sycl/test/devicelib/cmath_fp64_test.cpp @@ -3,22 +3,22 @@ // RUN: %CPU_RUN_PLACEHOLDER %t.out // RUN: %ACC_RUN_PLACEHOLDER %t.out +#include "math_utils.hpp" #include #include +#include #include -#include "math_utils.hpp" namespace s = cl::sycl; constexpr s::access::mode sycl_read = s::access::mode::read; constexpr s::access::mode sycl_write = s::access::mode::write; -#define TEST_NUM 38 +#define TEST_NUM 63 double ref[TEST_NUM] = { -1, 0, 0, 0, 0, 0, 0, 1, 1, 0.5, -0, 2, 0, 0, 1, 0, 2, 0, 0, 0, -0, 0, 1, 0, 1, 2, 0, 1, 2, 5, -0, 0, 0, 0, 0.5, 0.5, NAN, NAN,}; + 1, 0, 0, 0, 0, 0, 0, 1, 1, 0.5, 0, 2, 0, 0, 1, 0, 2, 0, 0, 0, 0, + 0, 1, 0, 1, 2, 0, 1, 2, 5, 0, 0, 0, 0, 0.5, 0.5, NAN, NAN, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; double refIptr = 1; @@ -47,6 +47,12 @@ void device_cmath_test(s::queue &deviceQueue) { auto quo_access = buffer4.template get_access(cgh); cgh.single_task([=]() { int i = 0; + T nan = NAN; + T minus_nan = -NAN; + T infinity = INFINITY; + T minus_infinity = -INFINITY; + double subnormal; + *((uint64_t *)&subnormal) = 0xFFFFFFFFFFFFFULL; res_access[i++] = std::cos(0.0); res_access[i++] = std::sin(0.0); res_access[i++] = std::log(1.0); @@ -83,9 +89,58 @@ void device_cmath_test(s::queue &deviceQueue) { res_access[i++] = std::logb(1.0); res_access[i++] = std::remainder(0.5, 1.0); res_access[i++] = std::remquo(0.5, 1.0, &quo_access[0]); - T a = NAN; - res_access[i++] = std::tgamma(a); - res_access[i++] = std::lgamma(a); + res_access[i++] = std::tgamma(nan); + res_access[i++] = std::lgamma(nan); + res_access[i++] = std::scalbn(1.0, 1); + + res_access[i++] = !(std::signbit(infinity) == 0); + res_access[i++] = !(std::signbit(minus_infinity) != 0); + res_access[i++] = !(std::signbit(nan) == 0); + res_access[i++] = !(std::signbit(minus_nan) != 0); + + res_access[i++] = !(std::isunordered(minus_nan, nan) != 0); + res_access[i++] = !(std::isunordered(minus_infinity, infinity) == 0); + res_access[i++] = !(std::isgreater(minus_infinity, infinity) == 0); + res_access[i++] = !(std::isgreater(0.0f, minus_nan) == 0); +#ifdef _WIN32 + res_access[i++] = !(std::isfinite(0.0f) != 0); + res_access[i++] = !(std::isfinite(nan) == 0); + res_access[i++] = !(std::isfinite(infinity) == 0); + res_access[i++] = !(std::isfinite(minus_infinity) == 0); + + res_access[i++] = !(std::isinf(0.0f) == 0); + res_access[i++] = !(std::isinf(nan) == 0); + res_access[i++] = !(std::isinf(infinity) != 0); + res_access[i++] = !(std::isinf(minus_infinity) != 0); +#else // !_WIN32 + // __builtin_isfinite is unsupported. + res_access[i++] = 0; + res_access[i++] = 0; + res_access[i++] = 0; + res_access[i++] = 0; + + // __builtin_isinf is unsupported. + res_access[i++] = 0; + res_access[i++] = 0; + res_access[i++] = 0; + res_access[i++] = 0; +#endif // !_WIN32 + res_access[i++] = !(std::isnan(0.0f) == 0); + res_access[i++] = !(std::isnan(nan) != 0); + res_access[i++] = !(std::isnan(infinity) == 0); + res_access[i++] = !(std::isnan(minus_infinity) == 0); +#ifdef _WIN32 + res_access[i++] = !(std::isnormal(nan) == 0); + res_access[i++] = !(std::isnormal(minus_infinity) == 0); + res_access[i++] = !(std::isnormal(subnormal) == 0); + res_access[i++] = !(std::isnormal(1.0f) != 0); +#else // !_WIN32 + // __builtin_isnormal() is unsupported. + res_access[i++] = 0; + res_access[i++] = 0; + res_access[i++] = 0; + res_access[i++] = 0; +#endif // !_WIN32 }); }); } diff --git a/sycl/test/devicelib/cmath_test.cpp b/sycl/test/devicelib/cmath_test.cpp index e07ac0f55003e..3774df5d6bd12 100644 --- a/sycl/test/devicelib/cmath_test.cpp +++ b/sycl/test/devicelib/cmath_test.cpp @@ -6,17 +6,19 @@ #include "math_utils.hpp" #include #include +#include #include namespace s = cl::sycl; constexpr s::access::mode sycl_read = s::access::mode::read; constexpr s::access::mode sycl_write = s::access::mode::write; -#define TEST_NUM 36 +#define TEST_NUM 61 -float ref[TEST_NUM] = {1, 0, 0, 0, 0, 0, 0, 1, 1, 0.5, 0, 0, - 1, 0, 2, 0, 0, 0, 0, 0, 1, 0, 1, 2, - 0, 1, 2, 5, 0, 0, 0, 0, 0.5, 0.5, NAN, NAN}; +float ref[TEST_NUM] = {1, 0, 0, 0, 0, 0, 0, 1, 1, 0.5, 0, 0, 1, 0, 2, 0, + 0, 0, 0, 0, 1, 0, 1, 2, 0, 1, 2, 5, 0, 0, 0, 0, + 0.5, 0.5, NAN, NAN, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; float refIptr = 1; @@ -39,6 +41,13 @@ template void device_cmath_test_1(s::queue &deviceQueue) { auto quo_access = buffer3.template get_access(cgh); cgh.single_task([=]() { int i = 0; + T nan = NAN; + T minus_nan = -NAN; + T infinity = INFINITY; + T minus_infinity = -INFINITY; + float subnormal; + *((uint32_t *)&subnormal) = 0x7FFFFF; + res_access[i++] = std::cos(0.0f); res_access[i++] = std::sin(0.0f); res_access[i++] = std::log(1.0f); @@ -73,9 +82,58 @@ template void device_cmath_test_1(s::queue &deviceQueue) { res_access[i++] = std::logb(1.0f); res_access[i++] = std::remainder(0.5f, 1.0f); res_access[i++] = std::remquo(0.5f, 1.0f, &quo_access[0]); - T a = NAN; - res_access[i++] = std::tgamma(a); - res_access[i++] = std::lgamma(a); + res_access[i++] = std::tgamma(nan); + res_access[i++] = std::lgamma(nan); + res_access[i++] = std::scalbn(1.0f, 1); + + res_access[i++] = !(std::signbit(infinity) == 0); + res_access[i++] = !(std::signbit(minus_infinity) != 0); + res_access[i++] = !(std::signbit(nan) == 0); + res_access[i++] = !(std::signbit(minus_nan) != 0); + + res_access[i++] = !(std::isunordered(minus_nan, nan) != 0); + res_access[i++] = !(std::isunordered(minus_infinity, infinity) == 0); + res_access[i++] = !(std::isgreater(minus_infinity, infinity) == 0); + res_access[i++] = !(std::isgreater(0.0f, minus_nan) == 0); +#ifdef _WIN32 + res_access[i++] = !(std::isfinite(0.0f) != 0); + res_access[i++] = !(std::isfinite(nan) == 0); + res_access[i++] = !(std::isfinite(infinity) == 0); + res_access[i++] = !(std::isfinite(minus_infinity) == 0); + + res_access[i++] = !(std::isinf(0.0f) == 0); + res_access[i++] = !(std::isinf(nan) == 0); + res_access[i++] = !(std::isinf(infinity) != 0); + res_access[i++] = !(std::isinf(minus_infinity) != 0); +#else // !_WIN32 + // __builtin_isfinite is unsupported. + res_access[i++] = 0; + res_access[i++] = 0; + res_access[i++] = 0; + res_access[i++] = 0; + + // __builtin_isinf is unsupported. + res_access[i++] = 0; + res_access[i++] = 0; + res_access[i++] = 0; + res_access[i++] = 0; +#endif // !_WIN32 + res_access[i++] = !(std::isnan(0.0f) == 0); + res_access[i++] = !(std::isnan(nan) != 0); + res_access[i++] = !(std::isnan(infinity) == 0); + res_access[i++] = !(std::isnan(minus_infinity) == 0); +#ifdef _WIN32 + res_access[i++] = !(std::isnormal(nan) == 0); + res_access[i++] = !(std::isnormal(minus_infinity) == 0); + res_access[i++] = !(std::isnormal(subnormal) == 0); + res_access[i++] = !(std::isnormal(1.0f) != 0); +#else // !_WIN32 + // __builtin_isnormal() is unsupported. + res_access[i++] = 0; + res_access[i++] = 0; + res_access[i++] = 0; + res_access[i++] = 0; +#endif // !_WIN32 }); }); } diff --git a/sycl/test/devicelib/math_fp64_test.cpp b/sycl/test/devicelib/math_fp64_test.cpp index 7f17fe63b3d01..7d07beffc0e40 100644 --- a/sycl/test/devicelib/math_fp64_test.cpp +++ b/sycl/test/devicelib/math_fp64_test.cpp @@ -5,6 +5,7 @@ #include "math_utils.hpp" #include +#include #include #include @@ -12,13 +13,12 @@ namespace s = cl::sycl; constexpr s::access::mode sycl_read = s::access::mode::read; constexpr s::access::mode sycl_write = s::access::mode::write; -#define TEST_NUM 38 +#define TEST_NUM 63 double ref_val[TEST_NUM] = { - 1, 0, 0, 0, 0, 0, 0, 1, 1, 0.5, - 0, 2, 0, 0, 1, 0, 2, 0, 0, 0, - 0, 0, 1, 0, 1, 2, 0, 1, 2, 5, - 0, 0, 0, 0, 0.5, 0.5, NAN, NAN}; + 1, 0, 0, 0, 0, 0, 0, 1, 1, 0.5, 0, 2, 0, 0, 1, 0, 2, 0, 0, 0, 0, + 0, 1, 0, 1, 2, 0, 1, 2, 5, 0, 0, 0, 0, 0.5, 0.5, NAN, NAN, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; double refIptr = 1; @@ -46,6 +46,13 @@ void device_math_test(s::queue &deviceQueue) { auto quo_access = buffer4.template get_access(cgh); cgh.single_task([=]() { int i = 0; + double nan = NAN; + double minus_nan = -NAN; + double infinity = INFINITY; + double minus_infinity = -INFINITY; + double subnormal; + *((uint64_t *)&subnormal) = 0xFFFFFFFFFFFFFULL; + res_access[i++] = cos(0.0); res_access[i++] = sin(0.0); res_access[i++] = log(1.0); @@ -82,9 +89,58 @@ void device_math_test(s::queue &deviceQueue) { res_access[i++] = logb(1.0); res_access[i++] = remainder(0.5, 1.0); res_access[i++] = remquo(0.5, 1.0, &quo_access[0]); - double a = NAN; - res_access[i++] = tgamma(a); - res_access[i++] = lgamma(a); + res_access[i++] = tgamma(nan); + res_access[i++] = lgamma(nan); + res_access[i++] = scalbn(1.0, 1); + + res_access[i++] = !(signbit(infinity) == 0); + res_access[i++] = !(signbit(minus_infinity) != 0); + res_access[i++] = !(signbit(nan) == 0); + res_access[i++] = !(signbit(minus_nan) != 0); + + res_access[i++] = !(isunordered(minus_nan, nan) != 0); + res_access[i++] = !(isunordered(minus_infinity, infinity) == 0); + res_access[i++] = !(isgreater(minus_infinity, infinity) == 0); + res_access[i++] = !(isgreater(0.0, minus_nan) == 0); +#ifdef _WIN32 + res_access[i++] = !(isfinite(0.0) != 0); + res_access[i++] = !(isfinite(nan) == 0); + res_access[i++] = !(isfinite(infinity) == 0); + res_access[i++] = !(isfinite(minus_infinity) == 0); + + res_access[i++] = !(isinf(0.0) == 0); + res_access[i++] = !(isinf(nan) == 0); + res_access[i++] = !(isinf(infinity) != 0); + res_access[i++] = !(isinf(minus_infinity) != 0); +#else // !_WIN32 + // __builtin_isfinite is unsupported. + res_access[i++] = 0; + res_access[i++] = 0; + res_access[i++] = 0; + res_access[i++] = 0; + + // __builtin_isinf is unsupported. + res_access[i++] = 0; + res_access[i++] = 0; + res_access[i++] = 0; + res_access[i++] = 0; +#endif // !_WIN32 + res_access[i++] = !(isnan(0.0) == 0); + res_access[i++] = !(isnan(nan) != 0); + res_access[i++] = !(isnan(infinity) == 0); + res_access[i++] = !(isnan(minus_infinity) == 0); +#ifdef _WIN32 + res_access[i++] = !(isnormal(nan) == 0); + res_access[i++] = !(isnormal(minus_infinity) == 0); + res_access[i++] = !(isnormal(subnormal) == 0); + res_access[i++] = !(isnormal(1.0) != 0); +#else // !_WIN32 + // __builtin_isnormal() is unsupported. + res_access[i++] = 0; + res_access[i++] = 0; + res_access[i++] = 0; + res_access[i++] = 0; +#endif // !_WIN32 }); }); } diff --git a/sycl/test/devicelib/math_test.cpp b/sycl/test/devicelib/math_test.cpp index 38d9a8f081bd9..8a23a0e28f33c 100644 --- a/sycl/test/devicelib/math_test.cpp +++ b/sycl/test/devicelib/math_test.cpp @@ -5,6 +5,7 @@ #include "math_utils.hpp" #include +#include #include #include @@ -12,11 +13,12 @@ namespace s = cl::sycl; constexpr s::access::mode sycl_read = s::access::mode::read; constexpr s::access::mode sycl_write = s::access::mode::write; -#define TEST_NUM 36 +#define TEST_NUM 61 -float ref_val[TEST_NUM] = {1, 0, 0, 0, 0, 0, 0, 1, 1, 0.5, 0, 0, - 1, 0, 2, 0, 0, 0, 0, 0, 1, 0, 1, 2, - 0, 1, 2, 5, 0, 0, 0, 0, 0.5, 0.5, NAN, NAN}; +float ref_val[TEST_NUM] = { + 1, 0, 0, 0, 0, 0, 0, 1, 1, 0.5, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 1, + 0, 1, 2, 0, 1, 2, 5, 0, 0, 0, 0, 0.5, 0.5, NAN, NAN, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; float refIptr = 1; @@ -39,6 +41,13 @@ void device_math_test(s::queue &deviceQueue) { auto quo_access = buffer3.template get_access(cgh); cgh.single_task([=]() { int i = 0; + float nan = NAN; + float minus_nan = -NAN; + float infinity = INFINITY; + float minus_infinity = -INFINITY; + float subnormal; + *((uint32_t *)&subnormal) = 0x7FFFFF; + res_access[i++] = cosf(0.0f); res_access[i++] = sinf(0.0f); res_access[i++] = logf(1.0f); @@ -73,9 +82,58 @@ void device_math_test(s::queue &deviceQueue) { res_access[i++] = logbf(1.0f); res_access[i++] = remainderf(0.5f, 1.0f); res_access[i++] = remquof(0.5f, 1.0f, &quo_access[0]); - float a = NAN; - res_access[i++] = tgammaf(a); - res_access[i++] = lgammaf(a); + res_access[i++] = tgammaf(nan); + res_access[i++] = lgammaf(nan); + res_access[i++] = scalbnf(1.0f, 1); + + res_access[i++] = !(signbit(infinity) == 0); + res_access[i++] = !(signbit(minus_infinity) != 0); + res_access[i++] = !(signbit(nan) == 0); + res_access[i++] = !(signbit(minus_nan) != 0); + + res_access[i++] = !(isunordered(minus_nan, nan) != 0); + res_access[i++] = !(isunordered(minus_infinity, infinity) == 0); + res_access[i++] = !(isgreater(minus_infinity, infinity) == 0); + res_access[i++] = !(isgreater(0.0f, minus_nan) == 0); +#ifdef _WIN32 + res_access[i++] = !(isfinite(0.0f) != 0); + res_access[i++] = !(isfinite(nan) == 0); + res_access[i++] = !(isfinite(infinity) == 0); + res_access[i++] = !(isfinite(minus_infinity) == 0); + + res_access[i++] = !(isinf(0.0f) == 0); + res_access[i++] = !(isinf(nan) == 0); + res_access[i++] = !(isinf(infinity) != 0); + res_access[i++] = !(isinf(minus_infinity) != 0); +#else // !_WIN32 + // __builtin_isfinite is unsupported. + res_access[i++] = 0; + res_access[i++] = 0; + res_access[i++] = 0; + res_access[i++] = 0; + + // __builtin_isinf is unsupported. + res_access[i++] = 0; + res_access[i++] = 0; + res_access[i++] = 0; + res_access[i++] = 0; +#endif // !_WIN32 + res_access[i++] = !(isnan(0.0f) == 0); + res_access[i++] = !(isnan(nan) != 0); + res_access[i++] = !(isnan(infinity) == 0); + res_access[i++] = !(isnan(minus_infinity) == 0); +#ifdef _WIN32 + res_access[i++] = !(isnormal(nan) == 0); + res_access[i++] = !(isnormal(minus_infinity) == 0); + res_access[i++] = !(isnormal(subnormal) == 0); + res_access[i++] = !(isnormal(1.0f) != 0); +#else // !_WIN32 + // __builtin_isnormal() is unsupported. + res_access[i++] = 0; + res_access[i++] = 0; + res_access[i++] = 0; + res_access[i++] = 0; +#endif // !_WIN32 }); }); }