[libc][math] Fix broken compilation due to __builtin_inf/nan functions.

This commit is contained in:
Kirill Okhotnikov 2022-06-25 01:39:32 +02:00
parent 87805d6a24
commit 27aca975b6
4 changed files with 22 additions and 24 deletions

View File

@ -135,6 +135,11 @@ template <typename T> struct FPBits {
return (bits & FloatProp::EXP_MANT_MASK) > FloatProp::EXPONENT_MASK;
}
bool is_quiet_nan() const {
return (bits & FloatProp::EXP_MANT_MASK) ==
(FloatProp::EXPONENT_MASK | FloatProp::QUIET_NAN_MASK);
}
bool is_inf_or_nan() const {
return (bits & FloatProp::EXPONENT_MASK) == FloatProp::EXPONENT_MASK;
}

View File

@ -65,22 +65,6 @@ template <typename T> static inline int unsafe_clz(T val) {
return __internal::clz(val);
}
template <typename T> static inline bool isnan(T val) {
return __builtin_isnan(val);
}
template <typename T> static inline bool isinf(T val) {
return __builtin_isinf(val);
}
template <typename T> static inline bool isfinite(T val) {
return __builtin_isfinite(val);
}
inline float quiet_NaN(float) { return __builtin_nanf(""); }
inline double quiet_NaN(double) { return __builtin_nan(""); }
inline long double quiet_NaN(long double) { return __builtin_nanl(""); }
} // namespace fputil
} // namespace __llvm_libc

View File

@ -115,28 +115,36 @@ namespace generic {
// https://man7.org/linux/man-pages/man3/fmod.3p.html
// C standard for the function is not full, so not by default (although it can
// be implemented in another handler.
// Signaling NaN converted to quiet NaN with FE_INVALID exception.
// https://www.open-std.org/JTC1/SC22/WG14/www/docs/n1011.htm
template <typename T> struct FModExceptionalInputHandler {
static_assert(cpp::IsFloatingPointType<T>::Value,
"FModCStandardWrapper instantiated with invalid type.");
static bool PreCheck(T x, T y, T &out) {
if (likely(y != 0 && fputil::isfinite(y) && fputil::isfinite(x))) {
using FPB = fputil::FPBits<T>;
const T quiet_NaN = FPB::build_nan(FPB::FloatProp::QUIET_NAN_MASK);
FPB sx(x), sy(y);
if (likely(!sy.is_zero() && !sy.is_inf_or_nan() && !sx.is_inf_or_nan())) {
return false;
}
if (fputil::isnan(x) || fputil::isnan(y)) {
out = fputil::quiet_NaN(T(0));
if (sx.is_nan() || sy.is_nan()) {
if ((sx.is_nan() && !sx.is_quiet_nan()) ||
(sy.is_nan() && !sy.is_quiet_nan()))
fputil::set_except(FE_INVALID);
out = quiet_NaN;
return true;
}
if (fputil::isinf(x) || y == 0) {
if (sx.is_inf() || sy.is_zero()) {
fputil::set_except(FE_INVALID);
out = with_errno(fputil::quiet_NaN(T(0)), EDOM);
out = with_errno(quiet_NaN, EDOM);
return true;
}
if (fputil::isinf(y)) {
if (sy.is_inf()) {
out = x;
return true;
}

View File

@ -51,8 +51,9 @@ inline void normalize<long double>(int &exponent, uint64_t &mantissa) {
template <>
inline void normalize<long double>(int &exponent, UInt128 &mantissa) {
const uint64_t hi_bits = static_cast<uint64_t>(mantissa >> 64);
const int shift = hi_bits ? (unsafe_clz(hi_bits) - 15)
: (unsafe_clz(static_cast<uint64_t>(mantissa)) + 49);
const int shift = hi_bits
? (unsafe_clz(hi_bits) - 15)
: (unsafe_clz(static_cast<uint64_t>(mantissa)) + 49);
exponent -= shift;
mantissa <<= shift;
}