diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt index 77c6244c5e5da..056f3e61b7e62 100644 --- a/libc/src/math/generic/CMakeLists.txt +++ b/libc/src/math/generic/CMakeLists.txt @@ -4129,7 +4129,9 @@ add_entrypoint_object( atan2f_float.h DEPENDS .inv_trigf_utils + libc.hdr.fenv_macros libc.src.__support.FPUtil.double_double + libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.fp_bits libc.src.__support.FPUtil.multiply_add libc.src.__support.FPUtil.nearest_integer @@ -4147,6 +4149,7 @@ add_entrypoint_object( DEPENDS .atan_utils libc.src.__support.FPUtil.double_double + libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.fp_bits libc.src.__support.FPUtil.multiply_add libc.src.__support.FPUtil.nearest_integer diff --git a/libc/src/math/generic/acosf.cpp b/libc/src/math/generic/acosf.cpp index 509a5ebc4973e..8dd6de2ce7474 100644 --- a/libc/src/math/generic/acosf.cpp +++ b/libc/src/math/generic/acosf.cpp @@ -84,10 +84,17 @@ LLVM_LIBC_FUNCTION(float, acosf, (float x)) { 0x1.921fb6p+1f) : /* x == 1.0f */ 0.0f; + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } + + // |x| <= +/-inf if (x_abs <= 0x7f80'0000U) { fputil::set_errno_if_required(EDOM); fputil::raise_except_if_required(FE_INVALID); } + return x + FPBits::quiet_nan().get_val(); } diff --git a/libc/src/math/generic/asinf.cpp b/libc/src/math/generic/asinf.cpp index da854417e85fe..12383bf6dacae 100644 --- a/libc/src/math/generic/asinf.cpp +++ b/libc/src/math/generic/asinf.cpp @@ -108,10 +108,16 @@ LLVM_LIBC_FUNCTION(float, asinf, (float x)) { // |x| > 1, return NaNs. if (LIBC_UNLIKELY(x_abs > 0x3f80'0000U)) { + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } + if (x_abs <= 0x7f80'0000U) { fputil::set_errno_if_required(EDOM); fputil::raise_except_if_required(FE_INVALID); } + return FPBits::quiet_nan().get_val(); } diff --git a/libc/src/math/generic/asinhf.cpp b/libc/src/math/generic/asinhf.cpp index 37b87a821222a..0bb7065eb1cfe 100644 --- a/libc/src/math/generic/asinhf.cpp +++ b/libc/src/math/generic/asinhf.cpp @@ -61,8 +61,14 @@ LLVM_LIBC_FUNCTION(float, asinhf, (float x)) { }; if (LIBC_UNLIKELY(x_abs >= 0x4bdd'65a5U)) { - if (LIBC_UNLIKELY(xbits.is_inf_or_nan())) + if (LIBC_UNLIKELY(xbits.is_inf_or_nan())) { + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits_t::quiet_nan().get_val(); + } + return x; + } // Exceptional cases when x > 2^24. switch (x_abs) { diff --git a/libc/src/math/generic/atan2.cpp b/libc/src/math/generic/atan2.cpp index 8adfe3321a9ee..aa770de33fb1f 100644 --- a/libc/src/math/generic/atan2.cpp +++ b/libc/src/math/generic/atan2.cpp @@ -8,6 +8,7 @@ #include "src/math/atan2.h" #include "atan_utils.h" +#include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/double_double.h" #include "src/__support/FPUtil/multiply_add.h" @@ -111,8 +112,11 @@ LLVM_LIBC_FUNCTION(double, atan2, (double y, double x)) { // Check for exceptional cases, whether inputs are 0, inf, nan, or close to // overflow, or close to underflow. if (LIBC_UNLIKELY(max_exp > 0x7ffU - 128U || min_exp < 128U)) { - if (x_bits.is_nan() || y_bits.is_nan()) + if (x_bits.is_nan() || y_bits.is_nan()) { + if (x_bits.is_signaling_nan() || y_bits.is_signaling_nan()) + fputil::raise_except_if_required(FE_INVALID); return FPBits::quiet_nan().get_val(); + } unsigned x_except = x == 0.0 ? 0 : (FPBits(x_abs).is_inf() ? 2 : 1); unsigned y_except = y == 0.0 ? 0 : (FPBits(y_abs).is_inf() ? 2 : 1); diff --git a/libc/src/math/generic/atan2f.cpp b/libc/src/math/generic/atan2f.cpp index 726cae9c8462b..c04b0eb1cc589 100644 --- a/libc/src/math/generic/atan2f.cpp +++ b/libc/src/math/generic/atan2f.cpp @@ -7,7 +7,9 @@ //===----------------------------------------------------------------------===// #include "src/math/atan2f.h" +#include "hdr/fenv_macros.h" #include "inv_trigf_utils.h" +#include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/PolyEval.h" #include "src/__support/FPUtil/double_double.h" @@ -264,8 +266,11 @@ LLVM_LIBC_FUNCTION(float, atan2f, (float y, float x)) { double den_d = static_cast(den_f); if (LIBC_UNLIKELY(max_abs >= 0x7f80'0000U || num_d == 0.0)) { - if (x_bits.is_nan() || y_bits.is_nan()) + if (x_bits.is_nan() || y_bits.is_nan()) { + if (x_bits.is_signaling_nan() || y_bits.is_signaling_nan()) + fputil::raise_except_if_required(FE_INVALID); return FPBits::quiet_nan().get_val(); + } double x_d = static_cast(x); double y_d = static_cast(y); size_t x_except = (x_d == 0.0) ? 0 : (x_abs == 0x7f80'0000 ? 2 : 1); diff --git a/libc/src/math/generic/atanhf.cpp b/libc/src/math/generic/atanhf.cpp index a2051bd3e3e67..2149314d2f676 100644 --- a/libc/src/math/generic/atanhf.cpp +++ b/libc/src/math/generic/atanhf.cpp @@ -24,6 +24,10 @@ LLVM_LIBC_FUNCTION(float, atanhf, (float x)) { // |x| >= 1.0 if (LIBC_UNLIKELY(x_abs >= 0x3F80'0000U)) { if (xbits.is_nan()) { + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } return x; } // |x| == 1.0 diff --git a/libc/src/math/generic/cos.cpp b/libc/src/math/generic/cos.cpp index b60082bf9c308..5da0f86812a89 100644 --- a/libc/src/math/generic/cos.cpp +++ b/libc/src/math/generic/cos.cpp @@ -65,7 +65,11 @@ LLVM_LIBC_FUNCTION(double, cos, (double x)) { } else { // Inf or NaN if (LIBC_UNLIKELY(x_e > 2 * FPBits::EXP_BIAS)) { - // sin(+-Inf) = NaN + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } + // cos(+-Inf) = NaN if (xbits.get_mantissa() == 0) { fputil::set_errno_if_required(EDOM); fputil::raise_except_if_required(FE_INVALID); diff --git a/libc/src/math/generic/cosf.cpp b/libc/src/math/generic/cosf.cpp index 6ea24f9ccd3fa..7cdae09869588 100644 --- a/libc/src/math/generic/cosf.cpp +++ b/libc/src/math/generic/cosf.cpp @@ -117,6 +117,11 @@ LLVM_LIBC_FUNCTION(float, cosf, (float x)) { // x is inf or nan. if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) { + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } + if (x_abs == 0x7f80'0000U) { fputil::set_errno_if_required(EDOM); fputil::raise_except_if_required(FE_INVALID); diff --git a/libc/src/math/generic/cosf16.cpp b/libc/src/math/generic/cosf16.cpp index 4d42db981ce71..99bb03eb71426 100644 --- a/libc/src/math/generic/cosf16.cpp +++ b/libc/src/math/generic/cosf16.cpp @@ -67,6 +67,11 @@ LLVM_LIBC_FUNCTION(float16, cosf16, (float16 x)) { // cos(+/-inf) = NaN, and cos(NaN) = NaN if (xbits.is_inf_or_nan()) { + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } + if (xbits.is_inf()) { fputil::set_errno_if_required(EDOM); fputil::raise_except_if_required(FE_INVALID); diff --git a/libc/src/math/generic/cospif.cpp b/libc/src/math/generic/cospif.cpp index 29566f4fceacf..5b6880f853b26 100644 --- a/libc/src/math/generic/cospif.cpp +++ b/libc/src/math/generic/cospif.cpp @@ -66,6 +66,11 @@ LLVM_LIBC_FUNCTION(float, cospif, (float x)) { // x is inf or nan. if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) { + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } + if (x_abs == 0x7f80'0000U) { fputil::set_errno_if_required(EDOM); fputil::raise_except_if_required(FE_INVALID); diff --git a/libc/src/math/generic/cospif16.cpp b/libc/src/math/generic/cospif16.cpp index ee74bdb4a3693..9dc25920d5cfe 100644 --- a/libc/src/math/generic/cospif16.cpp +++ b/libc/src/math/generic/cospif16.cpp @@ -54,6 +54,10 @@ LLVM_LIBC_FUNCTION(float16, cospif16, (float16 x)) { // Check for NaN or infintiy values if (LIBC_UNLIKELY(x_abs >= 0x7c00)) { + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } // If value is equal to infinity if (x_abs == 0x7c00) { fputil::set_errno_if_required(EDOM); diff --git a/libc/src/math/generic/erff.cpp b/libc/src/math/generic/erff.cpp index 016afe4a68140..44607a52a2e57 100644 --- a/libc/src/math/generic/erff.cpp +++ b/libc/src/math/generic/erff.cpp @@ -135,6 +135,10 @@ LLVM_LIBC_FUNCTION(float, erff, (float x)) { int sign = xbits.is_neg() ? 1 : 0; if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) { + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } return (x_abs > 0x7f80'0000) ? x : ONE[sign]; } diff --git a/libc/src/math/generic/log1p.cpp b/libc/src/math/generic/log1p.cpp index 058409fed081d..09f465a6ba774 100644 --- a/libc/src/math/generic/log1p.cpp +++ b/libc/src/math/generic/log1p.cpp @@ -910,7 +910,12 @@ LLVM_LIBC_FUNCTION(double, log1p, (double x)) { return FPBits_t::quiet_nan().get_val(); } // x is +Inf or NaN - return x; + if (xbits.is_inf() && xbits.is_pos()) + return x; + + if (xbits.is_signaling_nan()) + fputil::raise_except_if_required(FE_INVALID); + return FPBits_t::quiet_nan().get_val(); } x_dd.hi = x; } else { diff --git a/libc/src/math/generic/logf.cpp b/libc/src/math/generic/logf.cpp index 032d658a941be..e8d2ba2cfe175 100644 --- a/libc/src/math/generic/logf.cpp +++ b/libc/src/math/generic/logf.cpp @@ -132,6 +132,11 @@ LLVM_LIBC_FUNCTION(float, logf, (float x)) { return FPBits::quiet_nan().get_val(); } // x is +inf or nan + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } + return x; } } diff --git a/libc/src/math/generic/pow.cpp b/libc/src/math/generic/pow.cpp index 8a12934f6c4ba..43e99a7acf690 100644 --- a/libc/src/math/generic/pow.cpp +++ b/libc/src/math/generic/pow.cpp @@ -217,6 +217,11 @@ LLVM_LIBC_FUNCTION(double, pow, (double x, double y)) { uint64_t sign = 0; ///////// BEGIN - Check exceptional cases //////////////////////////////////// + // If x or y is signaling NaN + if (x_abs.is_signaling_nan() || y_abs.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } // The double precision number that is closest to 1 is (1 - 2^-53), which has // log2(1 - 2^-53) ~ -1.715...p-53. diff --git a/libc/src/math/generic/powf.cpp b/libc/src/math/generic/powf.cpp index 2d7deca3c77bb..dfdfd5d6d5760 100644 --- a/libc/src/math/generic/powf.cpp +++ b/libc/src/math/generic/powf.cpp @@ -664,6 +664,12 @@ LLVM_LIBC_FUNCTION(float, powf, (float x, float y)) { // |y * log2(x)| = 0 or > 151. // Hence x^y will either overflow or underflow if x is not zero. if (LIBC_UNLIKELY((y_abs & 0x0007'ffff) == 0) || (y_abs > 0x4f170000)) { + // y is signaling NaN + if (xbits.is_signaling_nan() || ybits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FloatBits::quiet_nan().get_val(); + } + // Exceptional exponents. if (y == 0.0f) return 1.0f; @@ -736,8 +742,8 @@ LLVM_LIBC_FUNCTION(float, powf, (float x, float y)) { } } if (y_abs > 0x4f17'0000) { + // if y is NaN if (y_abs > 0x7f80'0000) { - // y is NaN if (x_u == 0x3f80'0000) { // x = 1.0f // pow(1, NaN) = 1 return 1.0f; @@ -759,6 +765,12 @@ LLVM_LIBC_FUNCTION(float, powf, (float x, float y)) { // y is finite and non-zero. if (LIBC_UNLIKELY(((x_u & 0x801f'ffffU) == 0) || x_u >= 0x7f80'0000U || x_u < 0x0080'0000U)) { + // if x is signaling NaN + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FloatBits::quiet_nan().get_val(); + } + switch (x_u) { case 0x3f80'0000: // x = 1.0f return 1.0f; diff --git a/libc/src/math/generic/sin.cpp b/libc/src/math/generic/sin.cpp index 4a58dcf4b173f..65ac82f158ba0 100644 --- a/libc/src/math/generic/sin.cpp +++ b/libc/src/math/generic/sin.cpp @@ -77,6 +77,11 @@ LLVM_LIBC_FUNCTION(double, sin, (double x)) { // Inf or NaN if (LIBC_UNLIKELY(x_e > 2 * FPBits::EXP_BIAS)) { // sin(+-Inf) = NaN + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } + if (xbits.get_mantissa() == 0) { fputil::set_errno_if_required(EDOM); fputil::raise_except_if_required(FE_INVALID); diff --git a/libc/src/math/generic/sincos.cpp b/libc/src/math/generic/sincos.cpp index 0ac2f7f997527..08c8a8298f029 100644 --- a/libc/src/math/generic/sincos.cpp +++ b/libc/src/math/generic/sincos.cpp @@ -85,6 +85,12 @@ LLVM_LIBC_FUNCTION(void, sincos, (double x, double *sin_x, double *cos_x)) { } else { // Inf or NaN if (LIBC_UNLIKELY(x_e > 2 * FPBits::EXP_BIAS)) { + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + *sin_x = *cos_x = FPBits::quiet_nan().get_val(); + return; + } + // sin(+-Inf) = NaN if (xbits.get_mantissa() == 0) { fputil::set_errno_if_required(EDOM); diff --git a/libc/src/math/generic/sincosf.cpp b/libc/src/math/generic/sincosf.cpp index 623ef636afb1e..9c7bf181e485e 100644 --- a/libc/src/math/generic/sincosf.cpp +++ b/libc/src/math/generic/sincosf.cpp @@ -145,6 +145,12 @@ LLVM_LIBC_FUNCTION(void, sincosf, (float x, float *sinp, float *cosp)) { // x is inf or nan. if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) { + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + *sinp = *cosp = FPBits::quiet_nan().get_val(); + return; + } + if (x_abs == 0x7f80'0000U) { fputil::set_errno_if_required(EDOM); fputil::raise_except_if_required(FE_INVALID); diff --git a/libc/src/math/generic/sinf.cpp b/libc/src/math/generic/sinf.cpp index d27ce843a2c92..38ea56f5f28c6 100644 --- a/libc/src/math/generic/sinf.cpp +++ b/libc/src/math/generic/sinf.cpp @@ -136,6 +136,11 @@ LLVM_LIBC_FUNCTION(float, sinf, (float x)) { #endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) { + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } + if (x_abs == 0x7f80'0000U) { fputil::set_errno_if_required(EDOM); fputil::raise_except_if_required(FE_INVALID); diff --git a/libc/src/math/generic/sinf16.cpp b/libc/src/math/generic/sinf16.cpp index 85e55a614588a..28debbd52a9a5 100644 --- a/libc/src/math/generic/sinf16.cpp +++ b/libc/src/math/generic/sinf16.cpp @@ -87,6 +87,11 @@ LLVM_LIBC_FUNCTION(float16, sinf16, (float16 x)) { } if (xbits.is_inf_or_nan()) { + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } + if (xbits.is_inf()) { fputil::set_errno_if_required(EDOM); fputil::raise_except_if_required(FE_INVALID); diff --git a/libc/src/math/generic/sinpif.cpp b/libc/src/math/generic/sinpif.cpp index f572ded06b25a..492689d594d90 100644 --- a/libc/src/math/generic/sinpif.cpp +++ b/libc/src/math/generic/sinpif.cpp @@ -83,6 +83,11 @@ LLVM_LIBC_FUNCTION(float, sinpif, (float x)) { // check for NaN values if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) { + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } + if (x_abs == 0x7f80'0000U) { fputil::set_errno_if_required(EDOM); fputil::raise_except_if_required(FE_INVALID); diff --git a/libc/src/math/generic/sinpif16.cpp b/libc/src/math/generic/sinpif16.cpp index 51ea595653b4d..68af484a6c5d3 100644 --- a/libc/src/math/generic/sinpif16.cpp +++ b/libc/src/math/generic/sinpif16.cpp @@ -50,6 +50,10 @@ LLVM_LIBC_FUNCTION(float16, sinpif16, (float16 x)) { if (LIBC_UNLIKELY(x_abs >= 0x6400)) { // Check for NaN or infinity values if (LIBC_UNLIKELY(x_abs >= 0x7c00)) { + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } // If value is equal to infinity if (x_abs == 0x7c00) { fputil::set_errno_if_required(EDOM); diff --git a/libc/src/math/generic/tan.cpp b/libc/src/math/generic/tan.cpp index a899a2128d384..89b812cfc23a0 100644 --- a/libc/src/math/generic/tan.cpp +++ b/libc/src/math/generic/tan.cpp @@ -163,6 +163,10 @@ LLVM_LIBC_FUNCTION(double, tan, (double x)) { } else { // Inf or NaN if (LIBC_UNLIKELY(x_e > 2 * FPBits::EXP_BIAS)) { + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } // tan(+-Inf) = NaN if (xbits.get_mantissa() == 0) { fputil::set_errno_if_required(EDOM); diff --git a/libc/src/math/generic/tanf.cpp b/libc/src/math/generic/tanf.cpp index a15aa9796cbd8..ca5e35dca4c91 100644 --- a/libc/src/math/generic/tanf.cpp +++ b/libc/src/math/generic/tanf.cpp @@ -113,6 +113,11 @@ LLVM_LIBC_FUNCTION(float, tanf, (float x)) { if (LIBC_UNLIKELY(x_abs > 0x4d56'd354U)) { // Inf or NaN if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) { + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } + if (x_abs == 0x7f80'0000U) { fputil::set_errno_if_required(EDOM); fputil::raise_except_if_required(FE_INVALID); diff --git a/libc/src/math/generic/tanf16.cpp b/libc/src/math/generic/tanf16.cpp index 97d201b65bbe6..229f4a363670b 100644 --- a/libc/src/math/generic/tanf16.cpp +++ b/libc/src/math/generic/tanf16.cpp @@ -84,6 +84,10 @@ LLVM_LIBC_FUNCTION(float16, tanf16, (float16 x)) { // tan(+/-inf) = NaN, and tan(NaN) = NaN if (LIBC_UNLIKELY(x_abs >= 0x7c00)) { + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } // x = +/-inf if (x_abs == 0x7c00) { fputil::set_errno_if_required(EDOM); diff --git a/libc/src/math/generic/tanpif16.cpp b/libc/src/math/generic/tanpif16.cpp index 71cf25c9741a1..792d405b1bb9e 100644 --- a/libc/src/math/generic/tanpif16.cpp +++ b/libc/src/math/generic/tanpif16.cpp @@ -63,6 +63,11 @@ LLVM_LIBC_FUNCTION(float16, tanpif16, (float16 x)) { if (LIBC_UNLIKELY(x_abs >= 0x6400)) { // Check for NaN or infinity values if (LIBC_UNLIKELY(x_abs >= 0x7c00)) { + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } + // is inf if (x_abs == 0x7c00) { fputil::set_errno_if_required(EDOM); fputil::raise_except_if_required(FE_INVALID); diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt index 660b68687d63c..54f5e40cdce11 100644 --- a/libc/test/src/math/smoke/CMakeLists.txt +++ b/libc/test/src/math/smoke/CMakeLists.txt @@ -4228,6 +4228,7 @@ add_fp_unittest( SRCS pow_test.cpp DEPENDS + libc.src.errno.errno libc.hdr.fenv_macros libc.src.math.pow ) diff --git a/libc/test/src/math/smoke/acosf_test.cpp b/libc/test/src/math/smoke/acosf_test.cpp index e5d56c70f2722..74f68e00011aa 100644 --- a/libc/test/src/math/smoke/acosf_test.cpp +++ b/libc/test/src/math/smoke/acosf_test.cpp @@ -20,6 +20,9 @@ using LlvmLibcAcosfTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcAcosfTest, SpecialNumbers) { LIBC_NAMESPACE::libc_errno = 0; + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acosf(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acosf(aNaN)); EXPECT_MATH_ERRNO(0); diff --git a/libc/test/src/math/smoke/acoshf_test.cpp b/libc/test/src/math/smoke/acoshf_test.cpp index c4e88259919c3..c5ba88055ac57 100644 --- a/libc/test/src/math/smoke/acoshf_test.cpp +++ b/libc/test/src/math/smoke/acoshf_test.cpp @@ -20,6 +20,9 @@ using LlvmLibcAcoshfTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcAcoshfTest, SpecialNumbers) { LIBC_NAMESPACE::libc_errno = 0; + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf(aNaN)); EXPECT_MATH_ERRNO(0); diff --git a/libc/test/src/math/smoke/asinf_test.cpp b/libc/test/src/math/smoke/asinf_test.cpp index ce1576e2b57df..d817d2b366192 100644 --- a/libc/test/src/math/smoke/asinf_test.cpp +++ b/libc/test/src/math/smoke/asinf_test.cpp @@ -20,6 +20,9 @@ using LlvmLibcAsinfTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcAsinfTest, SpecialNumbers) { LIBC_NAMESPACE::libc_errno = 0; + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::asinf(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::asinf(aNaN)); EXPECT_MATH_ERRNO(0); diff --git a/libc/test/src/math/smoke/asinhf_test.cpp b/libc/test/src/math/smoke/asinhf_test.cpp index 5b83ce6466113..4a8743c50075f 100644 --- a/libc/test/src/math/smoke/asinhf_test.cpp +++ b/libc/test/src/math/smoke/asinhf_test.cpp @@ -20,6 +20,9 @@ using LlvmLibcAsinhfTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcAsinhfTest, SpecialNumbers) { LIBC_NAMESPACE::libc_errno = 0; + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::asinhf(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::asinhf(aNaN)); EXPECT_MATH_ERRNO(0); diff --git a/libc/test/src/math/smoke/atan2_test.cpp b/libc/test/src/math/smoke/atan2_test.cpp index 1606c3f378cb8..a79845fa0303d 100644 --- a/libc/test/src/math/smoke/atan2_test.cpp +++ b/libc/test/src/math/smoke/atan2_test.cpp @@ -13,6 +13,18 @@ using LlvmLibcAtan2Test = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcAtan2Test, SpecialNumbers) { + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::atan2(sNaN, sNaN), + FE_INVALID); + EXPECT_MATH_ERRNO(0); + + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::atan2(sNaN, 1.0), + FE_INVALID); + EXPECT_MATH_ERRNO(0); + + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::atan2(1.0, sNaN), + FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atan2(aNaN, zero)); EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atan2(1.0, aNaN)); EXPECT_FP_EQ_ALL_ROUNDING(0.0, LIBC_NAMESPACE::atan2(zero, zero)); diff --git a/libc/test/src/math/smoke/atan2f_test.cpp b/libc/test/src/math/smoke/atan2f_test.cpp index 94ec18d8f6b14..1fbcfbe96b2d7 100644 --- a/libc/test/src/math/smoke/atan2f_test.cpp +++ b/libc/test/src/math/smoke/atan2f_test.cpp @@ -18,6 +18,18 @@ using LlvmLibcAtan2fTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcAtan2fTest, SpecialNumbers) { LIBC_NAMESPACE::libc_errno = 0; + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::atan2f(sNaN, sNaN), + FE_INVALID); + EXPECT_MATH_ERRNO(0); + + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::atan2f(sNaN, 1.0f), + FE_INVALID); + EXPECT_MATH_ERRNO(0); + + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::atan2f(1.0f, sNaN), + FE_INVALID); + EXPECT_MATH_ERRNO(0); + // TODO: Strengthen errno,exception checks and remove these assert macros // after new matchers/test fixtures are added see: // https://github.com/llvm/llvm-project/issues/90653. diff --git a/libc/test/src/math/smoke/atan_test.cpp b/libc/test/src/math/smoke/atan_test.cpp index b83f315ec78fa..6576db9401c60 100644 --- a/libc/test/src/math/smoke/atan_test.cpp +++ b/libc/test/src/math/smoke/atan_test.cpp @@ -13,10 +13,10 @@ using LlvmLibcAtanTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcAtanTest, SpecialNumbers) { + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::atan(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atan(aNaN)); - // atan(sNaN) = aNaN. - EXPECT_EQ(FPBits(aNaN).uintval(), - FPBits(LIBC_NAMESPACE::atan(sNaN)).uintval()); EXPECT_FP_EQ_ALL_ROUNDING(zero, LIBC_NAMESPACE::atan(zero)); EXPECT_FP_EQ_ALL_ROUNDING(neg_zero, LIBC_NAMESPACE::atan(neg_zero)); // atan(+-Inf) = +- pi/2. diff --git a/libc/test/src/math/smoke/atanf_test.cpp b/libc/test/src/math/smoke/atanf_test.cpp index 346b8e8abd199..7d09a28beaa38 100644 --- a/libc/test/src/math/smoke/atanf_test.cpp +++ b/libc/test/src/math/smoke/atanf_test.cpp @@ -19,6 +19,8 @@ using LlvmLibcAtanfTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcAtanfTest, SpecialNumbers) { LIBC_NAMESPACE::libc_errno = 0; + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::atanf(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); // TODO: Strengthen errno,exception checks and remove these assert macros // after new matchers/test fixtures are added diff --git a/libc/test/src/math/smoke/atanhf_test.cpp b/libc/test/src/math/smoke/atanhf_test.cpp index 8300b47ea9a31..73a5b81b0240b 100644 --- a/libc/test/src/math/smoke/atanhf_test.cpp +++ b/libc/test/src/math/smoke/atanhf_test.cpp @@ -21,7 +21,8 @@ using LlvmLibcAtanhfTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcAtanhfTest, SpecialNumbers) { LIBC_NAMESPACE::libc_errno = 0; - + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::atanhf(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); // TODO: Strengthen errno,exception checks and remove these assert macros // after new matchers/test fixtures are added, see: // https://github.com/llvm/llvm-project/issues/90653 diff --git a/libc/test/src/math/smoke/cbrt_test.cpp b/libc/test/src/math/smoke/cbrt_test.cpp index 092e6dd1aeed3..9218f0f4092a7 100644 --- a/libc/test/src/math/smoke/cbrt_test.cpp +++ b/libc/test/src/math/smoke/cbrt_test.cpp @@ -15,6 +15,9 @@ using LlvmLibcCbrtTest = LIBC_NAMESPACE::testing::FPTest; using LIBC_NAMESPACE::testing::tlog; TEST_F(LlvmLibcCbrtTest, SpecialNumbers) { + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::cbrt(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::cbrt(aNaN)); EXPECT_FP_EQ_ALL_ROUNDING(inf, LIBC_NAMESPACE::cbrt(inf)); EXPECT_FP_EQ_ALL_ROUNDING(neg_inf, LIBC_NAMESPACE::cbrt(neg_inf)); diff --git a/libc/test/src/math/smoke/cbrtf_test.cpp b/libc/test/src/math/smoke/cbrtf_test.cpp index 202a5ce073358..5dcdf61dd9bff 100644 --- a/libc/test/src/math/smoke/cbrtf_test.cpp +++ b/libc/test/src/math/smoke/cbrtf_test.cpp @@ -15,6 +15,9 @@ using LlvmLibcCbrtfTest = LIBC_NAMESPACE::testing::FPTest; using LIBC_NAMESPACE::testing::tlog; TEST_F(LlvmLibcCbrtfTest, SpecialNumbers) { + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::cbrtf(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::cbrtf(aNaN)); EXPECT_FP_EQ_ALL_ROUNDING(inf, LIBC_NAMESPACE::cbrtf(inf)); EXPECT_FP_EQ_ALL_ROUNDING(neg_inf, LIBC_NAMESPACE::cbrtf(neg_inf)); diff --git a/libc/test/src/math/smoke/cos_test.cpp b/libc/test/src/math/smoke/cos_test.cpp index 88d8ead1af992..427d2c484302f 100644 --- a/libc/test/src/math/smoke/cos_test.cpp +++ b/libc/test/src/math/smoke/cos_test.cpp @@ -15,6 +15,9 @@ using LlvmLibcCosTest = LIBC_NAMESPACE::testing::FPTest; using LIBC_NAMESPACE::testing::tlog; TEST_F(LlvmLibcCosTest, SpecialNumbers) { + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::cos(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::cos(aNaN)); EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::cos(inf)); EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::cos(neg_inf)); diff --git a/libc/test/src/math/smoke/cosf16_test.cpp b/libc/test/src/math/smoke/cosf16_test.cpp index 9a51d1015da34..2638551fb1d1b 100644 --- a/libc/test/src/math/smoke/cosf16_test.cpp +++ b/libc/test/src/math/smoke/cosf16_test.cpp @@ -16,6 +16,9 @@ using LlvmLibcCosf16Test = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcCosf16Test, SpecialNumbers) { LIBC_NAMESPACE::libc_errno = 0; + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::cosf16(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::cosf16(aNaN)); EXPECT_MATH_ERRNO(0); diff --git a/libc/test/src/math/smoke/cosf_test.cpp b/libc/test/src/math/smoke/cosf_test.cpp index 2e261f9fac3c0..99773583dcb10 100644 --- a/libc/test/src/math/smoke/cosf_test.cpp +++ b/libc/test/src/math/smoke/cosf_test.cpp @@ -20,6 +20,9 @@ using LlvmLibcCosfTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcCosfTest, SpecialNumbers) { LIBC_NAMESPACE::libc_errno = 0; + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::cosf(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::cosf(aNaN)); EXPECT_MATH_ERRNO(0); diff --git a/libc/test/src/math/smoke/coshf_test.cpp b/libc/test/src/math/smoke/coshf_test.cpp index fd1556b10116d..1611ea1b92926 100644 --- a/libc/test/src/math/smoke/coshf_test.cpp +++ b/libc/test/src/math/smoke/coshf_test.cpp @@ -21,6 +21,9 @@ using LlvmLibcCoshfTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcCoshfTest, SpecialNumbers) { LIBC_NAMESPACE::libc_errno = 0; + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::coshf(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::coshf(aNaN)); EXPECT_MATH_ERRNO(0); diff --git a/libc/test/src/math/smoke/cospif16_test.cpp b/libc/test/src/math/smoke/cospif16_test.cpp index 135267ab2ae6f..edd8ed97b30f6 100644 --- a/libc/test/src/math/smoke/cospif16_test.cpp +++ b/libc/test/src/math/smoke/cospif16_test.cpp @@ -17,6 +17,9 @@ using LlvmLibcCospif16Test = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcCospif16Test, SpecialNumbers) { LIBC_NAMESPACE::libc_errno = 0; + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::cospif16(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::cospif16(aNaN)); EXPECT_MATH_ERRNO(0); diff --git a/libc/test/src/math/smoke/cospif_test.cpp b/libc/test/src/math/smoke/cospif_test.cpp index bf6d86bcfe623..20153897dc459 100644 --- a/libc/test/src/math/smoke/cospif_test.cpp +++ b/libc/test/src/math/smoke/cospif_test.cpp @@ -17,6 +17,9 @@ using LlvmLibcCospifTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcCospifTest, SpecialNumbers) { LIBC_NAMESPACE::libc_errno = 0; + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::cospif(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::cospif(aNaN)); EXPECT_MATH_ERRNO(0); diff --git a/libc/test/src/math/smoke/erff_test.cpp b/libc/test/src/math/smoke/erff_test.cpp index 7d2c1013752c7..a9f4994d77bb4 100644 --- a/libc/test/src/math/smoke/erff_test.cpp +++ b/libc/test/src/math/smoke/erff_test.cpp @@ -17,6 +17,9 @@ using LlvmLibcErffTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcErffTest, SpecialNumbers) { + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::erff(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::erff(aNaN)); EXPECT_FP_EQ_ALL_ROUNDING(1.0f, LIBC_NAMESPACE::erff(inf)); EXPECT_FP_EQ_ALL_ROUNDING(-1.0f, LIBC_NAMESPACE::erff(neg_inf)); diff --git a/libc/test/src/math/smoke/exp10_test.cpp b/libc/test/src/math/smoke/exp10_test.cpp index ca9fc359edeb5..baf8a76810970 100644 --- a/libc/test/src/math/smoke/exp10_test.cpp +++ b/libc/test/src/math/smoke/exp10_test.cpp @@ -18,6 +18,9 @@ using LlvmLibcExp10Test = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcExp10Test, SpecialNumbers) { + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::exp10(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::exp10(aNaN)); EXPECT_FP_EQ(inf, LIBC_NAMESPACE::exp10(inf)); EXPECT_FP_EQ_ALL_ROUNDING(zero, LIBC_NAMESPACE::exp10(neg_inf)); diff --git a/libc/test/src/math/smoke/exp10f_test.cpp b/libc/test/src/math/smoke/exp10f_test.cpp index bcbfc96efd726..bf39e2cc12d0c 100644 --- a/libc/test/src/math/smoke/exp10f_test.cpp +++ b/libc/test/src/math/smoke/exp10f_test.cpp @@ -20,6 +20,9 @@ using LlvmLibcExp10fTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcExp10fTest, SpecialNumbers) { LIBC_NAMESPACE::libc_errno = 0; + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::exp10f(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::exp10f(aNaN)); EXPECT_MATH_ERRNO(0); diff --git a/libc/test/src/math/smoke/exp10m1f_test.cpp b/libc/test/src/math/smoke/exp10m1f_test.cpp index 9c65a38425d77..2c2cfdbb08a3f 100644 --- a/libc/test/src/math/smoke/exp10m1f_test.cpp +++ b/libc/test/src/math/smoke/exp10m1f_test.cpp @@ -16,6 +16,9 @@ using LlvmLibcExp10m1fTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcExp10m1fTest, SpecialNumbers) { LIBC_NAMESPACE::libc_errno = 0; + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::exp10m1f(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_EQ(FPBits(aNaN).uintval(), FPBits(LIBC_NAMESPACE::exp10m1f(aNaN)).uintval()); EXPECT_EQ(FPBits(neg_aNaN).uintval(), diff --git a/libc/test/src/math/smoke/exp2_test.cpp b/libc/test/src/math/smoke/exp2_test.cpp index d97a384367a09..9ab9129416dad 100644 --- a/libc/test/src/math/smoke/exp2_test.cpp +++ b/libc/test/src/math/smoke/exp2_test.cpp @@ -18,6 +18,9 @@ using LlvmLibcExp2Test = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcExp2Test, SpecialNumbers) { + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::exp2(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::exp2(aNaN)); EXPECT_FP_EQ(inf, LIBC_NAMESPACE::exp2(inf)); EXPECT_FP_EQ_ALL_ROUNDING(zero, LIBC_NAMESPACE::exp2(neg_inf)); diff --git a/libc/test/src/math/smoke/exp2f_test.cpp b/libc/test/src/math/smoke/exp2f_test.cpp index d9cdecbf0fe9b..a928389cc41b4 100644 --- a/libc/test/src/math/smoke/exp2f_test.cpp +++ b/libc/test/src/math/smoke/exp2f_test.cpp @@ -20,6 +20,9 @@ using LlvmLibcExp2fTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcExp2fTest, SpecialNumbers) { LIBC_NAMESPACE::libc_errno = 0; + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::exp2f(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::exp2f(aNaN)); EXPECT_MATH_ERRNO(0); diff --git a/libc/test/src/math/smoke/exp2m1f_test.cpp b/libc/test/src/math/smoke/exp2m1f_test.cpp index 4657d088f07a8..99bdf0035df0c 100644 --- a/libc/test/src/math/smoke/exp2m1f_test.cpp +++ b/libc/test/src/math/smoke/exp2m1f_test.cpp @@ -18,6 +18,9 @@ using LIBC_NAMESPACE::fputil::testing::RoundingMode; TEST_F(LlvmLibcExp2m1fTest, SpecialNumbers) { LIBC_NAMESPACE::libc_errno = 0; + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::exp2m1f(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::exp2m1f(aNaN)); EXPECT_FP_EQ_ALL_ROUNDING(inf, LIBC_NAMESPACE::exp2m1f(inf)); EXPECT_FP_EQ_ALL_ROUNDING(-1.0f, LIBC_NAMESPACE::exp2m1f(neg_inf)); diff --git a/libc/test/src/math/smoke/exp_test.cpp b/libc/test/src/math/smoke/exp_test.cpp index d2467ff883896..f86243092f1fb 100644 --- a/libc/test/src/math/smoke/exp_test.cpp +++ b/libc/test/src/math/smoke/exp_test.cpp @@ -18,6 +18,9 @@ using LlvmLibcExpTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcExpTest, SpecialNumbers) { + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::exp(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::exp(aNaN)); EXPECT_FP_EQ(inf, LIBC_NAMESPACE::exp(inf)); EXPECT_FP_EQ_ALL_ROUNDING(zero, LIBC_NAMESPACE::exp(neg_inf)); diff --git a/libc/test/src/math/smoke/expf_test.cpp b/libc/test/src/math/smoke/expf_test.cpp index 11181ed1402c9..eee8304999275 100644 --- a/libc/test/src/math/smoke/expf_test.cpp +++ b/libc/test/src/math/smoke/expf_test.cpp @@ -20,6 +20,9 @@ using LlvmLibcExpfTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcExpfTest, SpecialNumbers) { LIBC_NAMESPACE::libc_errno = 0; + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::expf(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::expf(aNaN)); EXPECT_MATH_ERRNO(0); diff --git a/libc/test/src/math/smoke/expm1_test.cpp b/libc/test/src/math/smoke/expm1_test.cpp index cebd2d757606b..bc71c53abc7ac 100644 --- a/libc/test/src/math/smoke/expm1_test.cpp +++ b/libc/test/src/math/smoke/expm1_test.cpp @@ -18,6 +18,9 @@ using LlvmLibcExpm1Test = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcExpm1Test, SpecialNumbers) { + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::expm1(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::expm1(aNaN)); EXPECT_FP_EQ(inf, LIBC_NAMESPACE::expm1(inf)); EXPECT_FP_EQ_ALL_ROUNDING(-1.0, LIBC_NAMESPACE::expm1(neg_inf)); diff --git a/libc/test/src/math/smoke/expm1f_test.cpp b/libc/test/src/math/smoke/expm1f_test.cpp index f4138aa05ba7e..dfb474d70fb6a 100644 --- a/libc/test/src/math/smoke/expm1f_test.cpp +++ b/libc/test/src/math/smoke/expm1f_test.cpp @@ -20,6 +20,9 @@ using LlvmLibcExpm1fTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcExpm1fTest, SpecialNumbers) { LIBC_NAMESPACE::libc_errno = 0; + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::expm1f(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::expm1f(aNaN)); EXPECT_MATH_ERRNO(0); diff --git a/libc/test/src/math/smoke/log10_test.cpp b/libc/test/src/math/smoke/log10_test.cpp index 9f159f282aad8..ff73850c52101 100644 --- a/libc/test/src/math/smoke/log10_test.cpp +++ b/libc/test/src/math/smoke/log10_test.cpp @@ -18,6 +18,9 @@ using LlvmLibcLog10Test = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcLog10Test, SpecialNumbers) { + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::log10(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::log10(aNaN)); EXPECT_FP_EQ(inf, LIBC_NAMESPACE::log10(inf)); EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::log10(neg_inf), FE_INVALID); diff --git a/libc/test/src/math/smoke/log10f_test.cpp b/libc/test/src/math/smoke/log10f_test.cpp index 4e3bf654ca918..a63822140e9b9 100644 --- a/libc/test/src/math/smoke/log10f_test.cpp +++ b/libc/test/src/math/smoke/log10f_test.cpp @@ -17,6 +17,9 @@ using LlvmLibcLog10fTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcLog10fTest, SpecialNumbers) { + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::log10f(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::log10f(aNaN)); EXPECT_FP_EQ(inf, LIBC_NAMESPACE::log10f(inf)); EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::log10f(neg_inf), FE_INVALID); diff --git a/libc/test/src/math/smoke/log1p_test.cpp b/libc/test/src/math/smoke/log1p_test.cpp index b98c0f26a8bca..631c24b8abcf9 100644 --- a/libc/test/src/math/smoke/log1p_test.cpp +++ b/libc/test/src/math/smoke/log1p_test.cpp @@ -16,6 +16,9 @@ using LlvmLibcLog1pTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcLog1pTest, SpecialNumbers) { + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::log1p(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::log1p(aNaN)); EXPECT_FP_EQ(inf, LIBC_NAMESPACE::log1p(inf)); EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::log1p(neg_inf), FE_INVALID); diff --git a/libc/test/src/math/smoke/log1pf_test.cpp b/libc/test/src/math/smoke/log1pf_test.cpp index 1b0a1d589e684..bd828ad58c4c9 100644 --- a/libc/test/src/math/smoke/log1pf_test.cpp +++ b/libc/test/src/math/smoke/log1pf_test.cpp @@ -18,6 +18,9 @@ using LlvmLibcLog1pfTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcLog1pfTest, SpecialNumbers) { + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::log1pf(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::log1pf(aNaN)); EXPECT_FP_EQ(inf, LIBC_NAMESPACE::log1pf(inf)); EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::log1pf(neg_inf), FE_INVALID); diff --git a/libc/test/src/math/smoke/log2_test.cpp b/libc/test/src/math/smoke/log2_test.cpp index 1570d60556df2..9993d442967cb 100644 --- a/libc/test/src/math/smoke/log2_test.cpp +++ b/libc/test/src/math/smoke/log2_test.cpp @@ -18,6 +18,9 @@ using LlvmLibcLog2Test = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcLog2Test, SpecialNumbers) { + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::log2(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::log2(aNaN)); EXPECT_FP_EQ(inf, LIBC_NAMESPACE::log2(inf)); EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::log2(neg_inf), FE_INVALID); diff --git a/libc/test/src/math/smoke/log2f_test.cpp b/libc/test/src/math/smoke/log2f_test.cpp index 67b2c5b2db13d..8648b75b88b83 100644 --- a/libc/test/src/math/smoke/log2f_test.cpp +++ b/libc/test/src/math/smoke/log2f_test.cpp @@ -18,6 +18,9 @@ using LlvmLibcLog2fTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcLog2fTest, SpecialNumbers) { + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::log2f(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::log2f(aNaN)); EXPECT_FP_EQ(inf, LIBC_NAMESPACE::log2f(inf)); EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::log2f(neg_inf), FE_INVALID); diff --git a/libc/test/src/math/smoke/log_test.cpp b/libc/test/src/math/smoke/log_test.cpp index 20b974d7e167d..d31eb0c1db734 100644 --- a/libc/test/src/math/smoke/log_test.cpp +++ b/libc/test/src/math/smoke/log_test.cpp @@ -18,6 +18,9 @@ using LlvmLibcLogTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcLogTest, SpecialNumbers) { + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::log(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::log(aNaN)); EXPECT_FP_EQ(inf, LIBC_NAMESPACE::log(inf)); EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::log(neg_inf), FE_INVALID); diff --git a/libc/test/src/math/smoke/logf_test.cpp b/libc/test/src/math/smoke/logf_test.cpp index 1a3102ae2b141..faba50e9b240c 100644 --- a/libc/test/src/math/smoke/logf_test.cpp +++ b/libc/test/src/math/smoke/logf_test.cpp @@ -17,6 +17,9 @@ using LlvmLibcLogfTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcLogfTest, SpecialNumbers) { + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::logf(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::logf(aNaN)); EXPECT_FP_EQ(inf, LIBC_NAMESPACE::logf(inf)); EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::logf(neg_inf), FE_INVALID); diff --git a/libc/test/src/math/smoke/pow_test.cpp b/libc/test/src/math/smoke/pow_test.cpp index f9db7f102962b..b27134aca45d8 100644 --- a/libc/test/src/math/smoke/pow_test.cpp +++ b/libc/test/src/math/smoke/pow_test.cpp @@ -29,7 +29,33 @@ TEST_F(LlvmLibcPowTest, SpecialNumbers) { if (!__r.success) continue; + // pow( sNaN, exponent ) + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(sNaN, sNaN), + FE_INVALID); + EXPECT_FP_EQ_WITH_EXCEPTION( + aNaN, LIBC_NAMESPACE::pow(sNaN, NEG_ODD_INTEGER), FE_INVALID); + EXPECT_FP_EQ_WITH_EXCEPTION( + aNaN, LIBC_NAMESPACE::pow(sNaN, NEG_EVEN_INTEGER), FE_INVALID); + EXPECT_FP_EQ_WITH_EXCEPTION( + aNaN, LIBC_NAMESPACE::pow(sNaN, POS_ODD_INTEGER), FE_INVALID); + EXPECT_FP_EQ_WITH_EXCEPTION( + aNaN, LIBC_NAMESPACE::pow(sNaN, POS_EVEN_INTEGER), FE_INVALID); + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(sNaN, ONE_HALF), + FE_INVALID); + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(sNaN, zero), + FE_INVALID); + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(sNaN, neg_zero), + FE_INVALID); + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(sNaN, inf), + FE_INVALID); + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(sNaN, neg_inf), + FE_INVALID); + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(sNaN, aNaN), + FE_INVALID); + // pow( 0.0, exponent ) + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(zero, sNaN), + FE_INVALID); EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::pow(zero, NEG_ODD_INTEGER), FE_DIVBYZERO); EXPECT_FP_EQ_WITH_EXCEPTION( @@ -48,6 +74,8 @@ TEST_F(LlvmLibcPowTest, SpecialNumbers) { EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(zero, aNaN)); // pow( -0.0, exponent ) + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(neg_zero, sNaN), + FE_INVALID); EXPECT_FP_EQ_WITH_EXCEPTION( neg_inf, LIBC_NAMESPACE::pow(neg_zero, NEG_ODD_INTEGER), FE_DIVBYZERO); EXPECT_FP_EQ_WITH_EXCEPTION( @@ -66,6 +94,8 @@ TEST_F(LlvmLibcPowTest, SpecialNumbers) { EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(neg_zero, aNaN)); // pow( 1.0, exponent ) + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(1.0, sNaN), + FE_INVALID); EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, zero)); EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, neg_zero)); EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, 1.0)); @@ -80,7 +110,9 @@ TEST_F(LlvmLibcPowTest, SpecialNumbers) { EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, neg_inf)); EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, aNaN)); - // pow( 1.0, exponent ) + // pow( -1.0, exponent ) + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(-1.0, sNaN), + FE_INVALID); EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(-1.0, zero)); EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(-1.0, neg_zero)); EXPECT_FP_EQ(-1.0, LIBC_NAMESPACE::pow(-1.0, 1.0)); @@ -98,6 +130,8 @@ TEST_F(LlvmLibcPowTest, SpecialNumbers) { EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(-1.0, aNaN)); // pow( inf, exponent ) + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(inf, sNaN), + FE_INVALID); EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(inf, zero)); EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(inf, neg_zero)); EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(inf, 1.0)); @@ -114,6 +148,8 @@ TEST_F(LlvmLibcPowTest, SpecialNumbers) { EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(inf, aNaN)); // pow( -inf, exponent ) + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(neg_inf, sNaN), + FE_INVALID); EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(neg_inf, zero)); EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(neg_inf, neg_zero)); EXPECT_FP_EQ(neg_inf, LIBC_NAMESPACE::pow(neg_inf, 1.0)); @@ -130,6 +166,8 @@ TEST_F(LlvmLibcPowTest, SpecialNumbers) { EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(neg_inf, aNaN)); // pow ( aNaN, exponent ) + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(aNaN, sNaN), + FE_INVALID); EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(aNaN, zero)); EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(aNaN, neg_zero)); EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, 1.0)); diff --git a/libc/test/src/math/smoke/powf_test.cpp b/libc/test/src/math/smoke/powf_test.cpp index 9cc95ce0baef9..0d1a650385fbd 100644 --- a/libc/test/src/math/smoke/powf_test.cpp +++ b/libc/test/src/math/smoke/powf_test.cpp @@ -32,7 +32,33 @@ TEST_F(LlvmLibcPowfTest, SpecialNumbers) { if (!__r.success) continue; + // pow( sNaN, exponent) + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(sNaN, sNaN), + FE_INVALID); + EXPECT_FP_EQ_WITH_EXCEPTION( + aNaN, LIBC_NAMESPACE::powf(sNaN, neg_odd_integer), FE_INVALID); + EXPECT_FP_EQ_WITH_EXCEPTION( + aNaN, LIBC_NAMESPACE::powf(sNaN, neg_even_integer), FE_INVALID); + EXPECT_FP_EQ_WITH_EXCEPTION( + aNaN, LIBC_NAMESPACE::powf(sNaN, pos_odd_integer), FE_INVALID); + EXPECT_FP_EQ_WITH_EXCEPTION( + aNaN, LIBC_NAMESPACE::powf(sNaN, pos_even_integer), FE_INVALID); + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(sNaN, one_half), + FE_INVALID); + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(sNaN, zero), + FE_INVALID); + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(sNaN, neg_zero), + FE_INVALID); + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(sNaN, inf), + FE_INVALID); + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(sNaN, neg_inf), + FE_INVALID); + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(sNaN, aNaN), + FE_INVALID); + // pow( 0.0f, exponent ) + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(zero, sNaN), + FE_INVALID); EXPECT_FP_EQ_WITH_EXCEPTION( inf, LIBC_NAMESPACE::powf(zero, neg_odd_integer), FE_DIVBYZERO); EXPECT_FP_EQ_WITH_EXCEPTION( @@ -51,6 +77,8 @@ TEST_F(LlvmLibcPowfTest, SpecialNumbers) { EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(zero, aNaN)); // pow( -0.0f, exponent ) + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(neg_zero, sNaN), + FE_INVALID); EXPECT_FP_EQ_WITH_EXCEPTION( neg_inf, LIBC_NAMESPACE::powf(neg_zero, neg_odd_integer), FE_DIVBYZERO); EXPECT_FP_EQ_WITH_EXCEPTION( @@ -69,6 +97,8 @@ TEST_F(LlvmLibcPowfTest, SpecialNumbers) { EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(neg_zero, aNaN)); // pow( 1.0f, exponent ) + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(1.0f, sNaN), + FE_INVALID); EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, zero)); EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, neg_zero)); EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, 1.0f)); @@ -83,7 +113,9 @@ TEST_F(LlvmLibcPowfTest, SpecialNumbers) { EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, neg_inf)); EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(1.0f, aNaN)); - // pow( 1.0f, exponent ) + // pow( -1.0f, exponent ) + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(-1.0f, sNaN), + FE_INVALID); EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(-1.0f, zero)); EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(-1.0f, neg_zero)); EXPECT_FP_EQ(-1.0f, LIBC_NAMESPACE::powf(-1.0f, 1.0f)); @@ -101,6 +133,8 @@ TEST_F(LlvmLibcPowfTest, SpecialNumbers) { EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(-1.0f, aNaN)); // pow( inf, exponent ) + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(inf, sNaN), + FE_INVALID); EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(inf, zero)); EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(inf, neg_zero)); EXPECT_FP_EQ(inf, LIBC_NAMESPACE::powf(inf, 1.0f)); @@ -117,6 +151,8 @@ TEST_F(LlvmLibcPowfTest, SpecialNumbers) { EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(inf, aNaN)); // pow( -inf, exponent ) + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(neg_inf, sNaN), + FE_INVALID); EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(neg_inf, zero)); EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(neg_inf, neg_zero)); EXPECT_FP_EQ(neg_inf, LIBC_NAMESPACE::powf(neg_inf, 1.0f)); @@ -133,6 +169,8 @@ TEST_F(LlvmLibcPowfTest, SpecialNumbers) { EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(neg_inf, aNaN)); // pow ( aNaN, exponent ) + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(aNaN, sNaN), + FE_INVALID); EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(aNaN, zero)); EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::powf(aNaN, neg_zero)); EXPECT_FP_IS_NAN(LIBC_NAMESPACE::powf(aNaN, 1.0f)); @@ -160,6 +198,8 @@ TEST_F(LlvmLibcPowfTest, SpecialNumbers) { EXPECT_FP_EQ(zero, LIBC_NAMESPACE::powf(-1.1f, neg_inf)); // Exact powers of 2: + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(2.0f, sNaN), + FE_INVALID); EXPECT_FP_EQ(0x1.0p15f, LIBC_NAMESPACE::powf(2.0f, 15.0f)); EXPECT_FP_EQ(0x1.0p126f, LIBC_NAMESPACE::powf(2.0f, 126.0f)); EXPECT_FP_EQ(0x1.0p-45f, LIBC_NAMESPACE::powf(2.0f, -45.0f)); @@ -178,6 +218,8 @@ TEST_F(LlvmLibcPowfTest, SpecialNumbers) { EXPECT_FP_EQ(100000000.0f, LIBC_NAMESPACE::powf(10.0f, 8.0f)); EXPECT_FP_EQ(1000000000.0f, LIBC_NAMESPACE::powf(10.0f, 9.0f)); EXPECT_FP_EQ(10000000000.0f, LIBC_NAMESPACE::powf(10.0f, 10.0f)); + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::powf(10.0f, sNaN), + FE_INVALID); // Overflow / Underflow: if (ROUNDING_MODES[i] != RoundingMode::Downward && diff --git a/libc/test/src/math/smoke/sin_test.cpp b/libc/test/src/math/smoke/sin_test.cpp index 7dd1b7fda625b..da6d71bfcbe4c 100644 --- a/libc/test/src/math/smoke/sin_test.cpp +++ b/libc/test/src/math/smoke/sin_test.cpp @@ -15,6 +15,9 @@ using LlvmLibcSinTest = LIBC_NAMESPACE::testing::FPTest; using LIBC_NAMESPACE::testing::tlog; TEST_F(LlvmLibcSinTest, SpecialNumbers) { + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::sin(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::sin(aNaN)); EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::sin(inf)); EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::sin(neg_inf)); diff --git a/libc/test/src/math/smoke/sincos_test.cpp b/libc/test/src/math/smoke/sincos_test.cpp index 371c0ad63cbf5..8bc584de4e8cd 100644 --- a/libc/test/src/math/smoke/sincos_test.cpp +++ b/libc/test/src/math/smoke/sincos_test.cpp @@ -15,6 +15,11 @@ using LlvmLibcSincosTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcSincosTest, SpecialNumbers) { double sin_x, cos_x; + LIBC_NAMESPACE::sincos(sNaN, &sin_x, &cos_x); + EXPECT_FP_EQ_ALL_ROUNDING(aNaN, cos_x); + EXPECT_FP_EQ_ALL_ROUNDING(aNaN, sin_x); + EXPECT_MATH_ERRNO(0); + LIBC_NAMESPACE::sincos(aNaN, &sin_x, &cos_x); EXPECT_FP_EQ_ALL_ROUNDING(aNaN, cos_x); EXPECT_FP_EQ_ALL_ROUNDING(aNaN, sin_x); diff --git a/libc/test/src/math/smoke/sincosf_test.cpp b/libc/test/src/math/smoke/sincosf_test.cpp index e6896ca3dc21a..5f66868f12a1c 100644 --- a/libc/test/src/math/smoke/sincosf_test.cpp +++ b/libc/test/src/math/smoke/sincosf_test.cpp @@ -21,6 +21,11 @@ TEST_F(LlvmLibcSinCosfTest, SpecialNumbers) { LIBC_NAMESPACE::libc_errno = 0; float sin, cos; + LIBC_NAMESPACE::sincosf(sNaN, &sin, &cos); + EXPECT_FP_EQ(aNaN, cos); + EXPECT_FP_EQ(aNaN, sin); + EXPECT_MATH_ERRNO(0); + LIBC_NAMESPACE::sincosf(aNaN, &sin, &cos); EXPECT_FP_EQ(aNaN, cos); EXPECT_FP_EQ(aNaN, sin); diff --git a/libc/test/src/math/smoke/sinf16_test.cpp b/libc/test/src/math/smoke/sinf16_test.cpp index 2966c3c952fd2..a0e7a7ba321fd 100644 --- a/libc/test/src/math/smoke/sinf16_test.cpp +++ b/libc/test/src/math/smoke/sinf16_test.cpp @@ -16,6 +16,9 @@ using LlvmLibcSinf16Test = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcSinf16Test, SpecialNumbers) { LIBC_NAMESPACE::libc_errno = 0; + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::sinf16(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::sinf16(aNaN)); EXPECT_MATH_ERRNO(0); diff --git a/libc/test/src/math/smoke/sinf_test.cpp b/libc/test/src/math/smoke/sinf_test.cpp index 776c66dcb37bd..de504b4f5335c 100644 --- a/libc/test/src/math/smoke/sinf_test.cpp +++ b/libc/test/src/math/smoke/sinf_test.cpp @@ -20,6 +20,9 @@ using LlvmLibcSinfTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcSinfTest, SpecialNumbers) { LIBC_NAMESPACE::libc_errno = 0; + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::sinf(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::sinf(aNaN)); EXPECT_MATH_ERRNO(0); diff --git a/libc/test/src/math/smoke/sinhf_test.cpp b/libc/test/src/math/smoke/sinhf_test.cpp index 3cc0656967581..e22cfc7ea14d8 100644 --- a/libc/test/src/math/smoke/sinhf_test.cpp +++ b/libc/test/src/math/smoke/sinhf_test.cpp @@ -21,6 +21,9 @@ using LlvmLibcSinhfTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcSinhfTest, SpecialNumbers) { LIBC_NAMESPACE::libc_errno = 0; + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::sinhf(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::sinhf(aNaN)); EXPECT_MATH_ERRNO(0); diff --git a/libc/test/src/math/smoke/sinpif16_test.cpp b/libc/test/src/math/smoke/sinpif16_test.cpp index a79fd5281ee68..b2db6fb9f8626 100644 --- a/libc/test/src/math/smoke/sinpif16_test.cpp +++ b/libc/test/src/math/smoke/sinpif16_test.cpp @@ -17,6 +17,9 @@ using LlvmLibcSinpif16Test = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcSinpif16Test, SpecialNumbers) { LIBC_NAMESPACE::libc_errno = 0; + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::sinpif16(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::sinpif16(aNaN)); EXPECT_MATH_ERRNO(0); diff --git a/libc/test/src/math/smoke/sinpif_test.cpp b/libc/test/src/math/smoke/sinpif_test.cpp index 11bda0b6b28cc..1ba5c1d2b720a 100644 --- a/libc/test/src/math/smoke/sinpif_test.cpp +++ b/libc/test/src/math/smoke/sinpif_test.cpp @@ -17,6 +17,9 @@ using LlvmLibcSinpifTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcSinpifTest, SpecialNumbers) { LIBC_NAMESPACE::libc_errno = 0; + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::sinpif(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::sinpif(aNaN)); EXPECT_MATH_ERRNO(0); diff --git a/libc/test/src/math/smoke/tan_test.cpp b/libc/test/src/math/smoke/tan_test.cpp index aa5c23d65886d..6538990526753 100644 --- a/libc/test/src/math/smoke/tan_test.cpp +++ b/libc/test/src/math/smoke/tan_test.cpp @@ -15,6 +15,9 @@ using LlvmLibcTanTest = LIBC_NAMESPACE::testing::FPTest; using LIBC_NAMESPACE::testing::tlog; TEST_F(LlvmLibcTanTest, SpecialNumbers) { + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::tan(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::tan(aNaN)); EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::tan(inf)); EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::tan(neg_inf)); diff --git a/libc/test/src/math/smoke/tanf16_test.cpp b/libc/test/src/math/smoke/tanf16_test.cpp index 39d1182ba891e..f65b9fced72c4 100644 --- a/libc/test/src/math/smoke/tanf16_test.cpp +++ b/libc/test/src/math/smoke/tanf16_test.cpp @@ -17,6 +17,9 @@ using LlvmLibcTanf16Test = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcTanf16Test, SpecialNumbers) { LIBC_NAMESPACE::libc_errno = 0; + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::tanf16(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::tanf16(aNaN)); EXPECT_MATH_ERRNO(0); diff --git a/libc/test/src/math/smoke/tanf_test.cpp b/libc/test/src/math/smoke/tanf_test.cpp index 93fbfded3f66a..178e9065f430f 100644 --- a/libc/test/src/math/smoke/tanf_test.cpp +++ b/libc/test/src/math/smoke/tanf_test.cpp @@ -20,6 +20,9 @@ using LlvmLibcTanfTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcTanfTest, SpecialNumbers) { LIBC_NAMESPACE::libc_errno = 0; + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::tanf(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::tanf(aNaN)); EXPECT_MATH_ERRNO(0); diff --git a/libc/test/src/math/smoke/tanhf_test.cpp b/libc/test/src/math/smoke/tanhf_test.cpp index 3b7faa81dac2e..c09761ef531f2 100644 --- a/libc/test/src/math/smoke/tanhf_test.cpp +++ b/libc/test/src/math/smoke/tanhf_test.cpp @@ -20,6 +20,9 @@ using LlvmLibcTanhfTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcTanhfTest, SpecialNumbers) { LIBC_NAMESPACE::libc_errno = 0; + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::tanhf(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::tanhf(aNaN)); EXPECT_MATH_ERRNO(0); diff --git a/libc/test/src/math/smoke/tanpif16_test.cpp b/libc/test/src/math/smoke/tanpif16_test.cpp index a378cfb0a62e1..74797d1649b1a 100644 --- a/libc/test/src/math/smoke/tanpif16_test.cpp +++ b/libc/test/src/math/smoke/tanpif16_test.cpp @@ -16,6 +16,9 @@ using LlvmLibcTanpif16Test = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcTanpif16Test, SpecialNumbers) { LIBC_NAMESPACE::libc_errno = 0; + EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::tanpif16(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::tanpif16(aNaN)); EXPECT_MATH_ERRNO(0);