Skip to content

Commit

Permalink
[libc][math] Switch math functions to use libc_errno and fix some err…
Browse files Browse the repository at this point in the history
…no and floating point exceptions.

Switch math functions to use libc_errno and fix some errno and
floating point exceptions

Reviewed By: sivachandra

Differential Revision: https://reviews.llvm.org/D145349
  • Loading branch information
lntue committed Mar 7, 2023
1 parent 44a7358 commit 31c3943
Show file tree
Hide file tree
Showing 40 changed files with 108 additions and 111 deletions.
3 changes: 0 additions & 3 deletions libc/src/__support/FPUtil/CMakeLists.txt
Expand Up @@ -3,7 +3,6 @@ add_header_library(
HDRS
FEnvImpl.h
DEPENDS
libc.include.errno
libc.include.fenv
libc.include.math
libc.src.__support.macros.attributes
Expand Down Expand Up @@ -52,7 +51,6 @@ add_header_library(
libc.src.__support.CPP.type_traits
libc.src.__support.common
libc.include.math
libc.include.errno
libc.src.errno.errno
)

Expand Down Expand Up @@ -80,7 +78,6 @@ add_header_library(
libc.src.__support.common
libc.src.__support.macros.optimization
libc.include.math
libc.include.errno
libc.src.errno.errno
)

Expand Down
4 changes: 2 additions & 2 deletions libc/src/__support/FPUtil/FEnvImpl.h
Expand Up @@ -11,8 +11,8 @@

#include "src/__support/macros/attributes.h" // LIBC_INLINE
#include "src/__support/macros/properties/architectures.h"
#include "src/errno/libc_errno.h"

#include <errno.h>
#include <fenv.h>
#include <math.h>

Expand Down Expand Up @@ -71,7 +71,7 @@ LIBC_INLINE int raise_except_if_required(int excepts) {

LIBC_INLINE void set_errno_if_required(int err) {
if (math_errhandling & MATH_ERRNO)
errno = err;
libc_errno = err;
}

} // namespace __llvm_libc::fputil
Expand Down
7 changes: 2 additions & 5 deletions libc/src/__support/FPUtil/NearestIntegerOperations.h
Expand Up @@ -15,7 +15,6 @@
#include "src/__support/CPP/type_traits.h"
#include "src/__support/common.h"

#include <errno.h>
#include <math.h>

namespace __llvm_libc {
Expand Down Expand Up @@ -238,10 +237,8 @@ LIBC_INLINE I rounded_float_to_signed_integer(F x) {
constexpr I INTEGER_MAX = -(INTEGER_MIN + 1);
FPBits<F> bits(x);
auto set_domain_error_and_raise_invalid = []() {
if (math_errhandling & MATH_ERRNO)
errno = EDOM;
if (math_errhandling & MATH_ERREXCEPT)
raise_except(FE_INVALID);
set_errno_if_required(EDOM);
raise_except_if_required(FE_INVALID);
};

if (bits.is_inf_or_nan()) {
Expand Down
1 change: 1 addition & 0 deletions libc/src/math/generic/CMakeLists.txt
Expand Up @@ -774,6 +774,7 @@ add_entrypoint_object(
HDRS
../log10.h
DEPENDS
libc.src.__support.FPUtil.fenv_impl
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.multiply_add
libc.src.__support.FPUtil.double_double
Expand Down
3 changes: 1 addition & 2 deletions libc/src/math/generic/acosf.cpp
Expand Up @@ -79,8 +79,7 @@ LLVM_LIBC_FUNCTION(float, acosf, (float x)) {
fputil::set_errno_if_required(EDOM);
fputil::raise_except_if_required(FE_INVALID);
}
return x +
FPBits::build_nan(1 << (fputil::MantissaWidth<float>::VALUE - 1));
return x + FPBits::build_quiet_nan(0);
}

// When 0.5 < |x| <= 1, we perform range reduction as follow:
Expand Down
3 changes: 2 additions & 1 deletion libc/src/math/generic/acoshf.cpp
Expand Up @@ -25,7 +25,8 @@ LLVM_LIBC_FUNCTION(float, acoshf, (float x)) {

if (LIBC_UNLIKELY(x < 1.0f)) {
// x < 1.
fputil::set_except(FE_INVALID);
fputil::set_errno_if_required(EDOM);
fputil::raise_except_if_required(FE_INVALID);
return FPBits_t::build_quiet_nan(0);
}

Expand Down
14 changes: 7 additions & 7 deletions libc/src/math/generic/atanhf.cpp
Expand Up @@ -24,15 +24,15 @@ LLVM_LIBC_FUNCTION(float, atanhf, (float x)) {
if (xbits.is_nan()) {
return x;
}
// |x| == 0
// |x| == 1.0
if (x_abs == 0x3F80'0000U) {
fputil::set_except(FE_DIVBYZERO);
return with_errno(FPBits::inf(sign).get_val(), ERANGE);
fputil::set_errno_if_required(ERANGE);
fputil::raise_except_if_required(FE_DIVBYZERO);
return FPBits::inf(sign).get_val();
} else {
fputil::set_except(FE_INVALID);
return with_errno(
FPBits::build_nan(1 << (fputil::MantissaWidth<float>::VALUE - 1)),
EDOM);
fputil::set_errno_if_required(EDOM);
fputil::raise_except_if_required(FE_INVALID);
return FPBits::build_quiet_nan(0);
}
}

Expand Down
3 changes: 1 addition & 2 deletions libc/src/math/generic/cosf.cpp
Expand Up @@ -117,8 +117,7 @@ LLVM_LIBC_FUNCTION(float, cosf, (float x)) {
fputil::set_errno_if_required(EDOM);
fputil::raise_except_if_required(FE_INVALID);
}
return x +
FPBits::build_nan(1 << (fputil::MantissaWidth<float>::VALUE - 1));
return x + FPBits::build_quiet_nan(0);
}

// Combine the results with the sine of sum formula:
Expand Down
7 changes: 6 additions & 1 deletion libc/src/math/generic/log10.cpp
Expand Up @@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//

#include "src/math/log10.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/double_double.h"
#include "src/__support/FPUtil/dyadic_float.h"
Expand Down Expand Up @@ -953,9 +954,13 @@ LLVM_LIBC_FUNCTION(double, log10, (double x)) {
xbits.uintval() > FPBits_t::MAX_NORMAL)) {
if (xbits.is_zero()) {
// return -Inf and raise FE_DIVBYZERO.
return -1.0 / 0.0;
fputil::set_errno_if_required(ERANGE);
fputil::raise_except_if_required(FE_DIVBYZERO);
return static_cast<double>(FPBits_t::neg_inf());
}
if (xbits.get_sign() && !xbits.is_nan()) {
fputil::set_errno_if_required(EDOM);
fputil::raise_except_if_required(FE_INVALID);
return FPBits_t::build_quiet_nan(0);
}
if (xbits.is_inf_or_nan()) {
Expand Down
6 changes: 4 additions & 2 deletions libc/src/math/generic/log10f.cpp
Expand Up @@ -152,12 +152,14 @@ LLVM_LIBC_FUNCTION(float, log10f, (float x)) {
if (LIBC_UNLIKELY(x_u < FPBits::MIN_NORMAL || x_u > FPBits::MAX_NORMAL)) {
if (xbits.is_zero()) {
// Return -inf and raise FE_DIVBYZERO
fputil::raise_except(FE_DIVBYZERO);
fputil::set_errno_if_required(ERANGE);
fputil::raise_except_if_required(FE_DIVBYZERO);
return static_cast<float>(FPBits::neg_inf());
}
if (xbits.get_sign() && !xbits.is_nan()) {
// Return NaN and raise FE_INVALID
fputil::raise_except(FE_INVALID);
fputil::set_errno_if_required(EDOM);
fputil::raise_except_if_required(FE_INVALID);
return FPBits::build_quiet_nan(0);
}
if (xbits.is_inf_or_nan()) {
Expand Down
6 changes: 4 additions & 2 deletions libc/src/math/generic/log1pf.cpp
Expand Up @@ -45,7 +45,8 @@ LIBC_INLINE float log(double x) {

if (LIBC_UNLIKELY(x_u > FPBits::MAX_NORMAL)) {
if (xbits.get_sign() && !xbits.is_nan()) {
fputil::raise_except(FE_INVALID);
fputil::set_errno_if_required(EDOM);
fputil::raise_except_if_required(FE_INVALID);
return fputil::FPBits<float>::build_quiet_nan(0);
}
return static_cast<float>(x);
Expand Down Expand Up @@ -103,7 +104,8 @@ LLVM_LIBC_FUNCTION(float, log1pf, (float x)) {
case 0xbd1d20afU: // x = -0x1.3a415ep-5f
return fputil::round_result_slightly_up(-0x1.407112p-5f);
case 0xbf800000U: // x = -1.0
fputil::raise_except(FE_DIVBYZERO);
fputil::set_errno_if_required(ERANGE);
fputil::raise_except_if_required(FE_DIVBYZERO);
return static_cast<float>(fputil::FPBits<float>::neg_inf());
#ifndef LIBC_TARGET_CPU_HAS_FMA
case 0x4cc1c80bU: // x = 0x1.839016p+26f
Expand Down
4 changes: 3 additions & 1 deletion libc/src/math/generic/log2f.cpp
Expand Up @@ -121,10 +121,12 @@ LLVM_LIBC_FUNCTION(float, log2f, (float x)) {
// Exceptional inputs.
if (LIBC_UNLIKELY(x_u < FPBits::MIN_NORMAL || x_u > FPBits::MAX_NORMAL)) {
if (xbits.is_zero()) {
fputil::raise_except(FE_DIVBYZERO);
fputil::set_errno_if_required(ERANGE);
fputil::raise_except_if_required(FE_DIVBYZERO);
return static_cast<float>(FPBits::neg_inf());
}
if (xbits.get_sign() && !xbits.is_nan()) {
fputil::set_errno_if_required(EDOM);
fputil::raise_except(FE_INVALID);
return FPBits::build_quiet_nan(0);
}
Expand Down
6 changes: 4 additions & 2 deletions libc/src/math/generic/logf.cpp
Expand Up @@ -96,12 +96,14 @@ LLVM_LIBC_FUNCTION(float, logf, (float x)) {
if (LIBC_UNLIKELY(x_u < FPBits::MIN_NORMAL || x_u > FPBits::MAX_NORMAL)) {
if (xbits.is_zero()) {
// Return -inf and raise FE_DIVBYZERO
fputil::raise_except(FE_DIVBYZERO);
fputil::set_errno_if_required(ERANGE);
fputil::raise_except_if_required(FE_DIVBYZERO);
return static_cast<float>(FPBits::neg_inf());
}
if (xbits.get_sign() && !xbits.is_nan()) {
// Return NaN and raise FE_INVALID
fputil::raise_except(FE_INVALID);
fputil::set_errno_if_required(EDOM);
fputil::raise_except_if_required(FE_INVALID);
return FPBits::build_quiet_nan(0);
}
if (xbits.is_inf_or_nan()) {
Expand Down
3 changes: 1 addition & 2 deletions libc/src/math/generic/sinf.cpp
Expand Up @@ -138,8 +138,7 @@ LLVM_LIBC_FUNCTION(float, sinf, (float x)) {
fputil::set_errno_if_required(EDOM);
fputil::raise_except_if_required(FE_INVALID);
}
return x +
FPBits::build_nan(1 << (fputil::MantissaWidth<float>::VALUE - 1));
return x + FPBits::build_quiet_nan(0);
}

// Combine the results with the sine of sum formula:
Expand Down
3 changes: 1 addition & 2 deletions libc/src/math/generic/tanf.cpp
Expand Up @@ -114,8 +114,7 @@ LLVM_LIBC_FUNCTION(float, tanf, (float x)) {
fputil::set_errno_if_required(EDOM);
fputil::raise_except_if_required(FE_INVALID);
}
return x +
FPBits::build_nan(1 << (fputil::MantissaWidth<float>::VALUE - 1));
return x + FPBits::build_quiet_nan(0);
}
// Other large exceptional values
if (auto r = TANF_EXCEPTS.lookup_odd(x_abs, x_sign);
Expand Down
9 changes: 4 additions & 5 deletions libc/test/UnitTest/FPMatcher.h
Expand Up @@ -14,7 +14,6 @@
#include "test/UnitTest/Test.h"
#include "utils/testutils/RoundingModeUtils.h"

#include <errno.h>
#include <math.h>

namespace __llvm_libc {
Expand Down Expand Up @@ -106,17 +105,17 @@ FPMatcher<T, C> getMatcher(T expectedValue) {
#define EXPECT_MATH_ERRNO(expected) \
do { \
if (math_errhandling & MATH_ERRNO) { \
int actual = errno; \
errno = 0; \
int actual = libc_errno; \
libc_errno = 0; \
EXPECT_EQ(actual, expected); \
} \
} while (0)

#define ASSERT_MATH_ERRNO(expected) \
do { \
if (math_errhandling & MATH_ERRNO) { \
int actual = errno; \
errno = 0; \
int actual = libc_errno; \
libc_errno = 0; \
ASSERT_EQ(actual, expected); \
} \
} while (0)
Expand Down

0 comments on commit 31c3943

Please sign in to comment.