Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions libc/src/math/generic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
7 changes: 7 additions & 0 deletions libc/src/math/generic/acosf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

Expand Down
6 changes: 6 additions & 0 deletions libc/src/math/generic/asinf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

Expand Down
8 changes: 7 additions & 1 deletion libc/src/math/generic/asinhf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
6 changes: 5 additions & 1 deletion libc/src/math/generic/atan2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);

Expand Down
7 changes: 6 additions & 1 deletion libc/src/math/generic/atan2f.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
//===----------------------------------------------------------------------===//

#include "src/math/atan2f.h"
#include "hdr/fenv_macros.h"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are other .cpp files edited by this PR that use FE_INVALID but don't include hdr/fenv_macros.h. Maybe we should leave this for another PR though. Thoughts @lntue?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SGTM

#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"
Expand Down Expand Up @@ -264,8 +266,11 @@ LLVM_LIBC_FUNCTION(float, atan2f, (float y, float x)) {
double den_d = static_cast<double>(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<double>(x);
double y_d = static_cast<double>(y);
size_t x_except = (x_d == 0.0) ? 0 : (x_abs == 0x7f80'0000 ? 2 : 1);
Expand Down
4 changes: 4 additions & 0 deletions libc/src/math/generic/atanhf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 5 additions & 1 deletion libc/src/math/generic/cos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
5 changes: 5 additions & 0 deletions libc/src/math/generic/cosf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
5 changes: 5 additions & 0 deletions libc/src/math/generic/cosf16.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
5 changes: 5 additions & 0 deletions libc/src/math/generic/cospif.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions libc/src/math/generic/cospif16.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions libc/src/math/generic/erff.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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];
}

Expand Down
7 changes: 6 additions & 1 deletion libc/src/math/generic/log1p.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
5 changes: 5 additions & 0 deletions libc/src/math/generic/logf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down
5 changes: 5 additions & 0 deletions libc/src/math/generic/pow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
15 changes: 13 additions & 2 deletions libc/src/math/generic/powf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -736,8 +742,8 @@ LLVM_LIBC_FUNCTION(float, powf, (float x, float y)) {
}
}
if (y_abs > 0x4f17'0000) {
// 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;
Expand All @@ -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;
Expand Down Expand Up @@ -799,7 +811,6 @@ LLVM_LIBC_FUNCTION(float, powf, (float x, float y)) {
}

if (x_abs > 0x7f80'0000) {
// x is NaN.
// pow (aNaN, 0) is already taken care above.
return x;
}
Expand Down
5 changes: 5 additions & 0 deletions libc/src/math/generic/sin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 6 additions & 0 deletions libc/src/math/generic/sincos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 6 additions & 0 deletions libc/src/math/generic/sincosf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
5 changes: 5 additions & 0 deletions libc/src/math/generic/sinf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
5 changes: 5 additions & 0 deletions libc/src/math/generic/sinf16.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
5 changes: 5 additions & 0 deletions libc/src/math/generic/sinpif.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions libc/src/math/generic/sinpif16.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions libc/src/math/generic/tan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
5 changes: 5 additions & 0 deletions libc/src/math/generic/tanf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions libc/src/math/generic/tanf16.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Loading
Loading