forked from OSchip/llvm-project
[libc][math] Fix broken compilation due to __builtin_inf/nan functions.
This commit is contained in:
parent
87805d6a24
commit
27aca975b6
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue