[libc-commits] [libc] [libc][NFC] Introduce a Sign type for FPBits (PR #78500)
via libc-commits
libc-commits at lists.llvm.org
Wed Jan 17 12:30:49 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libc
Author: Guillaume Chatelet (gchatelet)
<details>
<summary>Changes</summary>
Another patch is needed to cover `DyadicFloat` and `NormalFloat` constructors.
---
Patch is 75.23 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/78500.diff
48 Files Affected:
- (modified) libc/src/__support/FPUtil/BasicOperations.h (+6-6)
- (modified) libc/src/__support/FPUtil/DivisionAndRemainderOperations.h (+3-3)
- (modified) libc/src/__support/FPUtil/FPBits.h (+76-42)
- (modified) libc/src/__support/FPUtil/ManipulationFunctions.h (+6-6)
- (modified) libc/src/__support/FPUtil/NearestIntegerOperations.h (+9-9)
- (modified) libc/src/__support/FPUtil/NormalFloat.h (+12-11)
- (modified) libc/src/__support/FPUtil/dyadic_float.h (+5-5)
- (modified) libc/src/__support/FPUtil/fpbits_str.h (+3-3)
- (modified) libc/src/__support/FPUtil/generic/FMA.h (+4-4)
- (modified) libc/src/__support/FPUtil/generic/FMod.h (+3-3)
- (modified) libc/src/__support/FPUtil/generic/sqrt.h (+2-2)
- (modified) libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h (+2-2)
- (modified) libc/src/__support/float_to_string.h (+1-1)
- (modified) libc/src/__support/str_to_float.h (+4-12)
- (modified) libc/src/math/generic/acosf.cpp (+2-1)
- (modified) libc/src/math/generic/asinf.cpp (+2-1)
- (modified) libc/src/math/generic/atanf.cpp (+6-4)
- (modified) libc/src/math/generic/atanhf.cpp (+2-1)
- (modified) libc/src/math/generic/cosf.cpp (+2-1)
- (modified) libc/src/math/generic/coshf.cpp (+2-1)
- (modified) libc/src/math/generic/erff.cpp (+1-1)
- (modified) libc/src/math/generic/exp10f_impl.h (+1-1)
- (modified) libc/src/math/generic/exp2f_impl.h (+1-1)
- (modified) libc/src/math/generic/expf.cpp (+1-1)
- (modified) libc/src/math/generic/expm1.cpp (+6-5)
- (modified) libc/src/math/generic/expm1f.cpp (+1-1)
- (modified) libc/src/math/generic/inv_trigf_utils.h (+6-5)
- (modified) libc/src/math/generic/log.cpp (+1-1)
- (modified) libc/src/math/generic/log10.cpp (+1-1)
- (modified) libc/src/math/generic/log10f.cpp (+1-1)
- (modified) libc/src/math/generic/log1p.cpp (+1-1)
- (modified) libc/src/math/generic/log1pf.cpp (+1-1)
- (modified) libc/src/math/generic/log2.cpp (+1-1)
- (modified) libc/src/math/generic/log2f.cpp (+1-1)
- (modified) libc/src/math/generic/logf.cpp (+1-1)
- (modified) libc/src/math/generic/powf.cpp (+14-12)
- (modified) libc/src/math/generic/sinf.cpp (+3-3)
- (modified) libc/src/math/generic/sinhf.cpp (+2-3)
- (modified) libc/src/math/generic/tanhf.cpp (+5-6)
- (modified) libc/src/stdio/printf_core/float_dec_converter.h (+10-12)
- (modified) libc/src/stdio/printf_core/float_hex_converter.h (+2-2)
- (modified) libc/src/stdio/printf_core/float_inf_nan_converter.h (+2-2)
- (modified) libc/test/src/__support/FPUtil/fpbits_test.cpp (+30-30)
- (modified) libc/test/src/math/RoundToIntegerTest.h (+3-2)
- (modified) libc/test/src/math/atanhf_test.cpp (+3-2)
- (modified) libc/test/src/math/smoke/atanhf_test.cpp (+3-2)
- (modified) libc/test/src/stdlib/strtold_test.cpp (+1-1)
- (modified) libc/test/src/time/difftime_test.cpp (+1-1)
``````````diff
diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h
index 2ec61517b0b8086..4015edb1b65372f 100644
--- a/libc/src/__support/FPUtil/BasicOperations.h
+++ b/libc/src/__support/FPUtil/BasicOperations.h
@@ -20,23 +20,23 @@ namespace fputil {
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
LIBC_INLINE T abs(T x) {
FPBits<T> bits(x);
- bits.set_sign(0);
+ bits.set_sign(Sign::POS);
return T(bits);
}
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
LIBC_INLINE T fmin(T x, T y) {
- FPBits<T> bitx(x), bity(y);
+ const FPBits<T> bitx(x), bity(y);
if (bitx.is_nan()) {
return y;
} else if (bity.is_nan()) {
return x;
- } else if (bitx.get_sign() != bity.get_sign()) {
+ } else if (bitx.sign() != bity.sign()) {
// To make sure that fmin(+0, -0) == -0 == fmin(-0, +0), whenever x and
// y has different signs and both are not NaNs, we return the number
// with negative sign.
- return (bitx.get_sign() ? x : y);
+ return ((bitx.is_neg()) ? x : y);
} else {
return (x < y ? x : y);
}
@@ -50,11 +50,11 @@ LIBC_INLINE T fmax(T x, T y) {
return y;
} else if (bity.is_nan()) {
return x;
- } else if (bitx.get_sign() != bity.get_sign()) {
+ } else if (bitx.sign() != bity.sign()) {
// To make sure that fmax(+0, -0) == +0 == fmax(-0, +0), whenever x and
// y has different signs and both are not NaNs, we return the number
// with positive sign.
- return (bitx.get_sign() ? y : x);
+ return (bitx.is_neg() ? y : x);
} else {
return (x > y ? x : y);
}
diff --git a/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h b/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h
index 65bbe6b099dd003..d3401b10a7cab81 100644
--- a/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h
+++ b/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h
@@ -43,13 +43,13 @@ LIBC_INLINE T remquo(T x, T y, int &q) {
return x;
}
- bool result_sign = (xbits.get_sign() == ybits.get_sign() ? false : true);
+ bool result_sign = (xbits.is_neg() == ybits.is_neg() ? false : true);
// Once we know the sign of the result, we can just operate on the absolute
// values. The correct sign can be applied to the result after the result
// is evaluated.
- xbits.set_sign(0);
- ybits.set_sign(0);
+ xbits.set_sign(Sign::POS);
+ ybits.set_sign(Sign::POS);
NormalFloat<T> normalx(xbits), normaly(ybits);
int exp = normalx.exponent - normaly.exponent;
diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index 4309a535abd0794..6a94798973e6345 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -31,6 +31,32 @@ enum class FPType {
X86_Binary80,
};
+// A type to interact with floating point type signs.
+// This may be moved outside of 'fputil' if useful.
+struct Sign {
+ LIBC_INLINE constexpr explicit Sign(bool is_negative)
+ : is_negative(is_negative) {}
+
+ LIBC_INLINE constexpr bool is_pos() const { return !is_negative; }
+ LIBC_INLINE constexpr bool is_neg() const { return is_negative; }
+
+ LIBC_INLINE friend constexpr bool operator==(Sign a, Sign b) {
+ return a.is_negative == b.is_negative;
+ }
+ LIBC_INLINE friend constexpr bool operator!=(Sign a, Sign b) {
+ return !(a == b);
+ }
+
+ static const Sign POS;
+ static const Sign NEG;
+
+private:
+ bool is_negative;
+};
+
+LIBC_INLINE_VAR constexpr Sign Sign::NEG = Sign(true);
+LIBC_INLINE_VAR constexpr Sign Sign::POS = Sign(false);
+
// The classes hierarchy is as follows:
//
// ┌───────────────────┐
@@ -273,9 +299,9 @@ struct FPRepBase : public internal::FPLayout<fp_type> {
return encode(exp) | encode(sig);
}
- LIBC_INLINE static constexpr StorageType encode(bool sign, BiasedExponent exp,
+ LIBC_INLINE static constexpr StorageType encode(Sign sign, BiasedExponent exp,
Significand sig) {
- if (sign)
+ if (sign.is_neg())
return SIGN_MASK | encode(exp, sig);
return encode(exp, sig);
}
@@ -309,12 +335,12 @@ struct FPRepBase : public internal::FPLayout<fp_type> {
StorageType bits = 0;
public:
- LIBC_INLINE constexpr bool get_sign() const {
- return (bits & SIGN_MASK) != 0;
+ LIBC_INLINE constexpr Sign sign() const {
+ return (bits & SIGN_MASK) ? Sign::NEG : Sign::POS;
}
- LIBC_INLINE constexpr void set_sign(bool signVal) {
- if (get_sign() != signVal)
+ LIBC_INLINE constexpr void set_sign(Sign signVal) {
+ if (sign() != signVal)
bits ^= SIGN_MASK;
}
@@ -363,6 +389,9 @@ struct FPRepBase : public internal::FPLayout<fp_type> {
LIBC_INLINE constexpr bool is_zero() const {
return (bits & EXP_SIG_MASK) == 0;
}
+
+ LIBC_INLINE constexpr bool is_neg() const { return sign().is_neg(); }
+ LIBC_INLINE constexpr bool is_pos() const { return sign().is_pos(); }
};
namespace internal {
@@ -421,35 +450,37 @@ template <FPType fp_type> struct FPRep : public FPRepBase<fp_type> {
return is_finite() && !is_subnormal();
}
- LIBC_INLINE static constexpr StorageType zero(bool sign = false) {
+ LIBC_INLINE static constexpr StorageType zero(Sign sign = Sign::POS) {
return encode(sign, BiasedExponent::BITS_ALL_ZEROES(), Significand::ZERO());
}
- LIBC_INLINE static constexpr StorageType one(bool sign = false) {
+ LIBC_INLINE static constexpr StorageType one(Sign sign = Sign::POS) {
return encode(sign, Exponent::ZERO(), Significand::ZERO());
}
- LIBC_INLINE static constexpr StorageType min_subnormal(bool sign = false) {
+ LIBC_INLINE static constexpr StorageType
+ min_subnormal(Sign sign = Sign::POS) {
return encode(sign, BiasedExponent::BITS_ALL_ZEROES(), Significand::LSB());
}
- LIBC_INLINE static constexpr StorageType max_subnormal(bool sign = false) {
+ LIBC_INLINE static constexpr StorageType
+ max_subnormal(Sign sign = Sign::POS) {
return encode(sign, BiasedExponent::BITS_ALL_ZEROES(),
Significand::BITS_ALL_ONES());
}
- LIBC_INLINE static constexpr StorageType min_normal(bool sign = false) {
+ LIBC_INLINE static constexpr StorageType min_normal(Sign sign = Sign::POS) {
return encode(sign, Exponent::MIN(), Significand::ZERO());
}
- LIBC_INLINE static constexpr StorageType max_normal(bool sign = false) {
+ LIBC_INLINE static constexpr StorageType max_normal(Sign sign = Sign::POS) {
return encode(sign, Exponent::MAX(), Significand::BITS_ALL_ONES());
}
- LIBC_INLINE static constexpr StorageType inf(bool sign = false) {
+ LIBC_INLINE static constexpr StorageType inf(Sign sign = Sign::POS) {
return encode(sign, BiasedExponent::BITS_ALL_ONES(), Significand::ZERO());
}
- LIBC_INLINE static constexpr StorageType build_nan(bool sign = false,
+ LIBC_INLINE static constexpr StorageType build_nan(Sign sign = Sign::POS,
StorageType v = 0) {
return encode(sign, BiasedExponent::BITS_ALL_ONES(),
(v ? Significand(v) : (Significand::MSB() >> 1)));
}
- LIBC_INLINE static constexpr StorageType build_quiet_nan(bool sign = false,
- StorageType v = 0) {
+ LIBC_INLINE static constexpr StorageType
+ build_quiet_nan(Sign sign = Sign::POS, StorageType v = 0) {
return encode(sign, BiasedExponent::BITS_ALL_ONES(),
Significand::MSB() | Significand(v));
}
@@ -539,36 +570,38 @@ struct FPRep<FPType::X86_Binary80> : public FPRepBase<FPType::X86_Binary80> {
return get_implicit_bit();
}
- LIBC_INLINE static constexpr StorageType zero(bool sign = false) {
+ LIBC_INLINE static constexpr StorageType zero(Sign sign = Sign::POS) {
return encode(sign, BiasedExponent::BITS_ALL_ZEROES(), Significand::ZERO());
}
- LIBC_INLINE static constexpr StorageType one(bool sign = false) {
+ LIBC_INLINE static constexpr StorageType one(Sign sign = Sign::POS) {
return encode(sign, Exponent::ZERO(), Significand::MSB());
}
- LIBC_INLINE static constexpr StorageType min_subnormal(bool sign = false) {
+ LIBC_INLINE static constexpr StorageType
+ min_subnormal(Sign sign = Sign::POS) {
return encode(sign, BiasedExponent::BITS_ALL_ZEROES(), Significand::LSB());
}
- LIBC_INLINE static constexpr StorageType max_subnormal(bool sign = false) {
+ LIBC_INLINE static constexpr StorageType
+ max_subnormal(Sign sign = Sign::POS) {
return encode(sign, BiasedExponent::BITS_ALL_ZEROES(),
Significand::BITS_ALL_ONES() ^ Significand::MSB());
}
- LIBC_INLINE static constexpr StorageType min_normal(bool sign = false) {
+ LIBC_INLINE static constexpr StorageType min_normal(Sign sign = Sign::POS) {
return encode(sign, Exponent::MIN(), Significand::MSB());
}
- LIBC_INLINE static constexpr StorageType max_normal(bool sign = false) {
+ LIBC_INLINE static constexpr StorageType max_normal(Sign sign = Sign::POS) {
return encode(sign, Exponent::MAX(), Significand::BITS_ALL_ONES());
}
- LIBC_INLINE static constexpr StorageType inf(bool sign = false) {
+ LIBC_INLINE static constexpr StorageType inf(Sign sign = Sign::POS) {
return encode(sign, BiasedExponent::BITS_ALL_ONES(), Significand::MSB());
}
- LIBC_INLINE static constexpr StorageType build_nan(bool sign = false,
+ LIBC_INLINE static constexpr StorageType build_nan(Sign sign = Sign::POS,
StorageType v = 0) {
return encode(sign, BiasedExponent::BITS_ALL_ONES(),
Significand::MSB() |
(v ? Significand(v) : (Significand::MSB() >> 2)));
}
- LIBC_INLINE static constexpr StorageType build_quiet_nan(bool sign = false,
- StorageType v = 0) {
+ LIBC_INLINE static constexpr StorageType
+ build_quiet_nan(Sign sign = Sign::POS, StorageType v = 0) {
return encode(sign, BiasedExponent::BITS_ALL_ONES(),
Significand::MSB() | (Significand::MSB() >> 1) |
Significand(v));
@@ -642,10 +675,10 @@ template <typename T> struct FPBits : public internal::FPRep<get_fp_type<T>()> {
// Constants.
static constexpr int MAX_BIASED_EXPONENT = (1 << EXP_LEN) - 1;
- static constexpr StorageType MIN_NORMAL = UP::min_normal(false);
- static constexpr StorageType MAX_NORMAL = UP::max_normal(false);
- static constexpr StorageType MIN_SUBNORMAL = UP::min_subnormal(false);
- static constexpr StorageType MAX_SUBNORMAL = UP::max_subnormal(false);
+ static constexpr StorageType MIN_NORMAL = UP::min_normal(Sign::POS);
+ static constexpr StorageType MAX_NORMAL = UP::max_normal(Sign::POS);
+ static constexpr StorageType MIN_SUBNORMAL = UP::min_subnormal(Sign::POS);
+ static constexpr StorageType MAX_SUBNORMAL = UP::max_subnormal(Sign::POS);
// Constructors.
LIBC_INLINE constexpr FPBits() = default;
@@ -675,45 +708,46 @@ template <typename T> struct FPBits : public internal::FPRep<get_fp_type<T>()> {
// Methods below this are used by tests.
- LIBC_INLINE static constexpr T zero(bool sign = false) {
+ LIBC_INLINE static constexpr T zero(Sign sign = Sign::POS) {
return FPBits(UP::zero(sign)).get_val();
}
- LIBC_INLINE static constexpr T neg_zero() { return zero(true); }
+ LIBC_INLINE static constexpr T neg_zero() { return zero(Sign::NEG); }
- LIBC_INLINE static constexpr T inf(bool sign = false) {
+ LIBC_INLINE static constexpr T inf(Sign sign = Sign::POS) {
return FPBits(UP::inf(sign)).get_val();
}
- LIBC_INLINE static constexpr T neg_inf() { return inf(true); }
+ LIBC_INLINE static constexpr T neg_inf() { return inf(Sign::NEG); }
LIBC_INLINE static constexpr T min_normal() {
- return FPBits(UP::min_normal(false)).get_val();
+ return FPBits(UP::min_normal(Sign::POS)).get_val();
}
LIBC_INLINE static constexpr T max_normal() {
- return FPBits(UP::max_normal(false)).get_val();
+ return FPBits(UP::max_normal(Sign::POS)).get_val();
}
LIBC_INLINE static constexpr T min_denormal() {
- return FPBits(UP::min_subnormal(false)).get_val();
+ return FPBits(UP::min_subnormal(Sign::POS)).get_val();
}
LIBC_INLINE static constexpr T max_denormal() {
- return FPBits(UP::max_subnormal(false)).get_val();
+ return FPBits(UP::max_subnormal(Sign::POS)).get_val();
}
LIBC_INLINE static constexpr T build_nan(StorageType v) {
- return FPBits(UP::build_nan(false, v)).get_val();
+ return FPBits(UP::build_nan(Sign::POS, v)).get_val();
}
- LIBC_INLINE static constexpr T build_quiet_nan(StorageType v) {
- return FPBits(UP::build_quiet_nan(false, v)).get_val();
+ LIBC_INLINE static constexpr T build_quiet_nan(StorageType v,
+ Sign sign = Sign::POS) {
+ return FPBits(UP::build_quiet_nan(sign, v)).get_val();
}
// TODO: Use an uint32_t for 'biased_exp'.
LIBC_INLINE static constexpr FPBits<T>
- create_value(bool sign, StorageType biased_exp, StorageType mantissa) {
+ create_value(Sign sign, StorageType biased_exp, StorageType mantissa) {
static_assert(get_fp_type<T>() != FPType::X86_Binary80,
"This function is not tested for X86 Extended Precision");
return FPBits(UP::encode(
diff --git a/libc/src/__support/FPUtil/ManipulationFunctions.h b/libc/src/__support/FPUtil/ManipulationFunctions.h
index 42433b9b8442db3..e0bd251883e20b8 100644
--- a/libc/src/__support/FPUtil/ManipulationFunctions.h
+++ b/libc/src/__support/FPUtil/ManipulationFunctions.h
@@ -49,13 +49,13 @@ LIBC_INLINE T modf(T x, T &iptr) {
return x;
} else if (bits.is_inf()) {
iptr = x;
- return bits.get_sign() ? T(FPBits<T>::neg_zero()) : T(FPBits<T>::zero());
+ return bits.is_neg() ? T(FPBits<T>::neg_zero()) : T(FPBits<T>::zero());
} else {
iptr = trunc(x);
if (x == iptr) {
// If x is already an integer value, then return zero with the right
// sign.
- return bits.get_sign() ? T(FPBits<T>::neg_zero()) : T(FPBits<T>::zero());
+ return bits.is_neg() ? T(FPBits<T>::neg_zero()) : T(FPBits<T>::zero());
} else {
return x - iptr;
}
@@ -65,7 +65,7 @@ LIBC_INLINE T modf(T x, T &iptr) {
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
LIBC_INLINE T copysign(T x, T y) {
FPBits<T> xbits(x);
- xbits.set_sign(FPBits<T>(y).get_sign());
+ xbits.set_sign(FPBits<T>(y).sign());
return T(xbits);
}
@@ -131,11 +131,11 @@ LIBC_INLINE T ldexp(T x, int exp) {
// calculating the limit.
int exp_limit = FPBits<T>::MAX_BIASED_EXPONENT + FPBits<T>::FRACTION_LEN + 1;
if (exp > exp_limit)
- return bits.get_sign() ? T(FPBits<T>::neg_inf()) : T(FPBits<T>::inf());
+ return bits.is_neg() ? T(FPBits<T>::neg_inf()) : T(FPBits<T>::inf());
// Similarly on the negative side we return zero early if |exp| is too small.
if (exp < -exp_limit)
- return bits.get_sign() ? T(FPBits<T>::neg_zero()) : T(FPBits<T>::zero());
+ return bits.is_neg() ? T(FPBits<T>::neg_zero()) : T(FPBits<T>::zero());
// For all other values, NormalFloat to T conversion handles it the right way.
NormalFloat<T> normal(bits);
@@ -173,7 +173,7 @@ LIBC_INLINE T nextafter(T from, U to) {
}
} else {
int_val = FPBits<T>::MIN_SUBNORMAL;
- if (to_bits.get_sign())
+ if (to_bits.is_neg())
int_val |= FPBits<T>::SIGN_MASK;
}
diff --git a/libc/src/__support/FPUtil/NearestIntegerOperations.h b/libc/src/__support/FPUtil/NearestIntegerOperations.h
index 64c44e0b3a0c44c..e32b4d27a7a1df9 100644
--- a/libc/src/__support/FPUtil/NearestIntegerOperations.h
+++ b/libc/src/__support/FPUtil/NearestIntegerOperations.h
@@ -41,7 +41,7 @@ LIBC_INLINE T trunc(T x) {
// If the exponent is such that abs(x) is less than 1, then return 0.
if (exponent <= -1) {
- if (bits.get_sign())
+ if (bits.is_neg())
return T(-0.0);
else
return T(0.0);
@@ -60,7 +60,7 @@ LIBC_INLINE T ceil(T x) {
if (bits.is_inf_or_nan() || bits.is_zero())
return x;
- bool is_neg = bits.get_sign();
+ bool is_neg = bits.is_neg();
int exponent = bits.get_exponent();
// If the exponent is greater than the most negative mantissa
@@ -93,7 +93,7 @@ LIBC_INLINE T ceil(T x) {
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
LIBC_INLINE T floor(T x) {
FPBits<T> bits(x);
- if (bits.get_sign()) {
+ if (bits.is_neg()) {
return -ceil(-x);
} else {
return trunc(x);
@@ -109,7 +109,7 @@ LIBC_INLINE T round(T x) {
if (bits.is_inf_or_nan() || bits.is_zero())
return x;
- bool is_neg = bits.get_sign();
+ bool is_neg = bits.is_neg();
int exponent = bits.get_exponent();
// If the exponent is greater than the most negative mantissa
@@ -161,7 +161,7 @@ LIBC_INLINE T round_using_current_rounding_mode(T x) {
if (bits.is_inf_or_nan() || bits.is_zero())
return x;
- bool is_neg = bits.get_sign();
+ bool is_neg = bits.is_neg();
int exponent = bits.get_exponent();
int rounding_mode = quick_get_round();
@@ -247,18 +247,18 @@ LIBC_INLINE I rounded_float_to_signed_integer(F x) {
if (bits.is_inf_or_nan()) {
set_domain_error_and_raise_invalid();
- return bits.get_sign() ? INTEGER_MIN : INTEGER_MAX;
+ return bits.is_neg() ? INTEGER_MIN : INTEGER_MAX;
}
int exponent = bits.get_exponent();
constexpr int EXPONENT_LIMIT = sizeof(I) * 8 - 1;
if (exponent > EXPONENT_LIMIT) {
set_domain_error_and_raise_invalid();
- return bits.get_sign() ? INTEGER_MIN : INTEGER_MAX;
+ return bits.is_neg() ? INTEGER_MIN : INTEGER_MAX;
} else if (exponent == EXPONENT_LIMIT) {
- if (bits.get_sign() == 0 || bits.get_mantissa() != 0) {
+ if (bits.is_neg() == 0 || bits.get_mantissa() != 0) {
set_domain_error_and_raise_invalid();
- return bits.get_sign() ? INTEGER_MIN : INTEGER_MAX;
+ return bits.is_neg() ? INTEGER_MIN : INTEGER_MAX;
}
// If the control reaches here, then it means that the rounded
// value is the most negative number for the signed integer type I.
diff --git a/libc/src/__support/FPUtil/NormalFloat.h b/libc/src/__support/FPUtil/NormalFloat.h
index e70c89a7dbe15aa..39376bfcba03196 100644
--- a/libc/src/__support/FPUtil/NormalFloat.h
+++ b/libc/src/__support/FPUtil/NormalFloat.h
@@ -44,10 +44,10 @@ template <typename T> struct NormalFloat {
static_assert(sizeof(StorageType) * 8 >= FPBits<T>::FRACTION_LEN + 1,
"Bad type for mantissa in NormalFloat.");
- bool sign;
+ Sign sign = Sign::POS;
LIBC_INLINE NormalFloat(int32_t e, StorageType m, bool s)
- : exponent(e), mantissa(m), sign(s) {
+ : exponent(e), mantissa(m), sign(Sign(s)) {
if (mantissa >= ONE)
return;
@@ -64,20 +64,21 @@ template <typename T> struct NormalFloat {
// Returns -1 is this number is less than |other|, 0 if this number is equal
// to |other|, and 1 if this number is greater than |other|.
LIBC_INLINE int cmp(const NormalFloat<T> &other) const {
+ const int result = sign.is_neg() ? -1 : 1;
if (sign != other.sign)
- return sign ? -1 : 1;
+ return result;
if (exponent > other.exponent) {
- return sign ? -1 : 1;
+ return result;
} else if (exponent == other.exponent) {
if (mantissa > other.mantissa)
- return sign ? -1 : 1;
+ return result;
else if (mantissa == other.mantissa)
return 0;
else
- return sign ? 1 : -1;
+ return -result;
} else {
- return sign ? 1 : -1;
+ return -result;
}
}
@@ -95,7 +96,7 @@ template <typename T> struct NormalFloat {
// Max exponent is of the form 0xFF...E. That is why -2 and not -1.
constexpr int MAX_EXPONENT_VALUE = (1 << FPBits<T>::EXP_LEN) - 2;
if (biased_exponent > MAX_EXPONENT_VALUE) {
- return sign ? T(FPBits<T>::neg_inf()) : T(FPBits<T>::inf());
+ return T(FPBits<T>::inf(sign));
}
FPBits<T> result(T(0.0));
@@ -141,7 +142,7 @@ template <typename T> struct NormalFloat {
private:
LIBC_INLINE void init_from_bits(FPBits<T> bits) {
- sign = bits.get_sign();
+ sign = bits.sign();
if (bits.is_inf_or_nan() || bits.is_zero()) {
// Ignore s...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/78500
More information about the libc-commits
mailing list