Skip to content

Commit

Permalink
Revert "[libc] Remove unnecessary FPBits functions and properties" (#…
Browse files Browse the repository at this point in the history
…79118)

Reverts #79113
It broke aarch64 build bot machines.
  • Loading branch information
gchatelet committed Jan 23, 2024
1 parent 8e09f13 commit b524eed
Show file tree
Hide file tree
Showing 68 changed files with 421 additions and 426 deletions.
2 changes: 1 addition & 1 deletion libc/fuzzing/stdlib/strtofloat_fuzz.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ using LIBC_NAMESPACE::fputil::FPBits;
// exponent. Subnormals have a lower effective precision since they don't
// necessarily use all of the bits of the mantissa.
template <typename F> inline constexpr int effective_precision(int exponent) {
const int full_precision = FPBits<F>::FRACTION_LEN + 1;
const int full_precision = FPBits<F>::MANTISSA_PRECISION;

// This is intended to be 0 when the exponent is the lowest normal and
// increase as the exponent's magnitude increases.
Expand Down
2 changes: 1 addition & 1 deletion libc/src/__support/FPUtil/DivisionAndRemainderOperations.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ LIBC_INLINE T remquo(T x, T y, int &q) {
if (ybits.is_nan())
return y;
if (xbits.is_inf() || ybits.is_zero())
return FPBits<T>::build_quiet_nan(fputil::Sign::POS, 1).get_val();
return FPBits<T>::build_quiet_nan(1);

if (xbits.is_zero()) {
q = 0;
Expand Down
51 changes: 42 additions & 9 deletions libc/src/__support/FPUtil/FPBits.h
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ struct FPRepSem : public FPStorage<fp_type> {
return exp_bits() == encode(BiasedExp::BITS_ALL_ZEROES());
}
LIBC_INLINE constexpr bool is_normal() const {
return is_finite() && !is_subnormal();
return is_finite() && !UP::is_subnormal();
}
// Returns the mantissa with the implicit bit set iff the current
// value is a valid normal number.
Expand Down Expand Up @@ -556,14 +556,6 @@ struct FPRep : public FPRepSem<fp_type, RetT> {
using UP::FRACTION_MASK;
using UP::SIGN_MASK;

// Comparison
LIBC_INLINE constexpr friend bool operator==(FPRep a, FPRep b) {
return a.uintval() == b.uintval();
}
LIBC_INLINE constexpr friend bool operator!=(FPRep a, FPRep b) {
return a.uintval() != b.uintval();
}

// Representation
LIBC_INLINE constexpr StorageType uintval() const { return bits & FP_MASK; }
LIBC_INLINE constexpr void set_uintval(StorageType value) {
Expand Down Expand Up @@ -706,6 +698,16 @@ struct FPBits final : public internal::FPRep<get_fp_type<T>(), FPBits<T>> {
using UP::bits;

// Constants.
LIBC_INLINE_VAR static constexpr uint32_t MANTISSA_PRECISION =
UP::FRACTION_LEN + 1;
LIBC_INLINE_VAR static constexpr StorageType MIN_NORMAL =
UP::min_normal(Sign::POS).uintval();
LIBC_INLINE_VAR static constexpr StorageType MAX_NORMAL =
UP::max_normal(Sign::POS).uintval();
LIBC_INLINE_VAR static constexpr StorageType MIN_SUBNORMAL =
UP::min_subnormal(Sign::POS).uintval();
LIBC_INLINE_VAR static constexpr StorageType MAX_SUBNORMAL =
UP::max_subnormal(Sign::POS).uintval();
LIBC_INLINE_VAR static constexpr int MAX_BIASED_EXPONENT =
(1 << UP::EXP_LEN) - 1;

Expand All @@ -729,6 +731,37 @@ struct FPBits final : public internal::FPRep<get_fp_type<T>(), FPBits<T>> {

LIBC_INLINE constexpr explicit operator T() const { return get_val(); }

// Methods below this are used by tests.
// TODO: inline and remove.
LIBC_INLINE static constexpr T one(Sign sign = Sign::POS) {
return T(UP::one(sign));
}
LIBC_INLINE static constexpr T zero(Sign sign = Sign::POS) {
return T(UP::zero(sign));
}
LIBC_INLINE static constexpr T inf(Sign sign = Sign::POS) {
return T(UP::inf(sign));
}
LIBC_INLINE static constexpr T min_normal() {
return T(UP::min_normal(Sign::POS));
}
LIBC_INLINE static constexpr T max_normal() {
return T(UP::max_normal(Sign::POS));
}
LIBC_INLINE static constexpr T min_denormal() {
return T(UP::min_subnormal(Sign::POS));
}
LIBC_INLINE static constexpr T max_denormal() {
return T(UP::max_subnormal(Sign::POS));
}
LIBC_INLINE static constexpr T build_nan(StorageType v) {
return T(UP::build_nan(Sign::POS, v));
}
LIBC_INLINE static constexpr T build_quiet_nan(StorageType v,
Sign sign = Sign::POS) {
return T(UP::build_quiet_nan(sign, v));
}

// TODO: Use an uint32_t for 'biased_exp'.
LIBC_INLINE static constexpr FPBits<T>
create_value(Sign sign, StorageType biased_exp, StorageType mantissa) {
Expand Down
4 changes: 2 additions & 2 deletions libc/src/__support/FPUtil/Hypot.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ LIBC_INLINE T hypot(T x, T y) {
if (int round_mode = quick_get_round();
round_mode == FE_TONEAREST || round_mode == FE_UPWARD)
return T(FPBits_t::inf());
return T(FPBits_t::max_normal());
return T(FPBits_t(FPBits_t::MAX_NORMAL));
}
} else {
// For denormal result, we simply move the leading bit of the result to
Expand Down Expand Up @@ -254,7 +254,7 @@ LIBC_INLINE T hypot(T x, T y) {
if (out_exp >= FPBits_t::MAX_BIASED_EXPONENT) {
if (round_mode == FE_TONEAREST || round_mode == FE_UPWARD)
return T(FPBits_t::inf());
return T(FPBits_t::max_normal());
return T(FPBits_t(FPBits_t::MAX_NORMAL));
}
}

Expand Down
24 changes: 14 additions & 10 deletions libc/src/__support/FPUtil/ManipulationFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ LIBC_INLINE T logb(T x) {
return x;
} else if (bits.is_inf()) {
// Return positive infinity.
return T(FPBits<T>::inf());
return T(FPBits<T>::inf(Sign::POS));
}

NormalFloat<T> normal(bits);
Expand All @@ -127,7 +127,7 @@ LIBC_INLINE T ldexp(T x, int exp) {
// that adding |exp| to it does not lead to integer rollover. But, if |exp|
// value is larger the exponent range for type T, then we can return infinity
// early. Because the result of the ldexp operation can be a subnormal number,
// we need to accommodate the (mantissaWidth + 1) worth of shift in
// we need to accommodate the (mantissaWidht + 1) worth of shift in
// calculating the limit.
int exp_limit = FPBits<T>::MAX_BIASED_EXPONENT + FPBits<T>::FRACTION_LEN + 1;
if (exp > exp_limit)
Expand Down Expand Up @@ -164,22 +164,26 @@ LIBC_INLINE T nextafter(T from, U to) {
return static_cast<T>(to);

using StorageType = typename FPBits<T>::StorageType;
if (from != T(0)) {
if ((static_cast<U>(from) < to) == (from > T(0))) {
from_bits = FPBits<T>(StorageType(from_bits.uintval() + 1));
StorageType int_val = from_bits.uintval();
if (from != FPBits<T>::zero()) {
if ((static_cast<U>(from) < to) == (from > FPBits<T>::zero())) {
++int_val;
} else {
from_bits = FPBits<T>(StorageType(from_bits.uintval() - 1));
--int_val;
}
} else {
from_bits = FPBits<T>::min_subnormal(to_bits.sign());
int_val = FPBits<T>::MIN_SUBNORMAL;
if (to_bits.is_neg())
int_val |= FPBits<T>::SIGN_MASK;
}

if (from_bits.is_subnormal())
StorageType exponent_bits = int_val & FPBits<T>::EXP_MASK;
if (exponent_bits == StorageType(0))
raise_except_if_required(FE_UNDERFLOW | FE_INEXACT);
else if (from_bits.is_inf())
else if (exponent_bits == FPBits<T>::EXP_MASK)
raise_except_if_required(FE_OVERFLOW | FE_INEXACT);

return from_bits.get_val();
return cpp::bit_cast<T>(int_val);
}

} // namespace fputil
Expand Down
2 changes: 1 addition & 1 deletion libc/src/__support/FPUtil/NormalFloat.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ template <> LIBC_INLINE NormalFloat<long double>::operator long double() const {
// Max exponent is of the form 0xFF...E. That is why -2 and not -1.
constexpr int MAX_EXPONENT_VALUE = (1 << LDBits::EXP_LEN) - 2;
if (biased_exponent > MAX_EXPONENT_VALUE) {
return LDBits::inf(sign).get_val();
return LDBits::inf(sign);
}

FPBits<long double> result(0.0l);
Expand Down
2 changes: 1 addition & 1 deletion libc/src/__support/FPUtil/dyadic_float.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ template <size_t Bits> struct DyadicFloat {
return 0.0;

// Assume that it is normalized, and output is also normal.
constexpr uint32_t PRECISION = FPBits<T>::FRACTION_LEN + 1;
constexpr uint32_t PRECISION = FPBits<T>::MANTISSA_PRECISION;
using output_bits_t = typename FPBits<T>::StorageType;

int exp_hi = exponent + static_cast<int>((Bits - 1) + FPBits<T>::EXP_BIAS);
Expand Down
6 changes: 4 additions & 2 deletions libc/src/__support/FPUtil/except_value_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,15 @@ template <typename T, size_t N> struct ExceptValues {
// Helper functions to set results for exceptional cases.
template <typename T> LIBC_INLINE T round_result_slightly_down(T value_rn) {
volatile T tmp = value_rn;
tmp -= FPBits<T>::min_normal().get_val();
const T MIN_NORMAL = FPBits<T>::min_normal();
tmp = tmp - MIN_NORMAL;
return tmp;
}

template <typename T> LIBC_INLINE T round_result_slightly_up(T value_rn) {
volatile T tmp = value_rn;
tmp += FPBits<T>::min_normal().get_val();
const T MIN_NORMAL = FPBits<T>::min_normal();
tmp = tmp + MIN_NORMAL;
return tmp;
}

Expand Down
10 changes: 6 additions & 4 deletions libc/src/__support/FPUtil/generic/FMA.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,9 @@ template <> LIBC_INLINE double fma<double>(double x, double y, double z) {
return x * y + z;

// Extract mantissa and append hidden leading bits.
UInt128 x_mant = x_bits.get_explicit_mantissa();
UInt128 y_mant = y_bits.get_explicit_mantissa();
UInt128 z_mant = z_bits.get_explicit_mantissa();
UInt128 x_mant = x_bits.get_mantissa() | FPBits::MIN_NORMAL;
UInt128 y_mant = y_bits.get_mantissa() | FPBits::MIN_NORMAL;
UInt128 z_mant = z_bits.get_mantissa() | FPBits::MIN_NORMAL;

// If the exponent of the product x*y > the exponent of z, then no extra
// precision beside the entire product x*y is needed. On the other hand, when
Expand Down Expand Up @@ -255,7 +255,9 @@ template <> LIBC_INLINE double fma<double>(double x, double y, double z) {
if ((round_mode == FE_TOWARDZERO) ||
(round_mode == FE_UPWARD && prod_sign.is_neg()) ||
(round_mode == FE_DOWNWARD && prod_sign.is_pos())) {
return FPBits::max_normal(prod_sign).get_val();
result = FPBits::MAX_NORMAL;
return prod_sign.is_neg() ? -cpp::bit_cast<double>(result)
: cpp::bit_cast<double>(result);
}
return static_cast<double>(FPBits::inf(prod_sign));
}
Expand Down
2 changes: 1 addition & 1 deletion libc/src/__support/FPUtil/generic/FMod.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ template <typename T> struct FModExceptionalInputHandler {

LIBC_INLINE static bool pre_check(T x, T y, T &out) {
using FPB = fputil::FPBits<T>;
const T quiet_nan = FPB::build_quiet_nan().get_val();
const T quiet_nan = FPB::build_quiet_nan(0);
FPB sx(x), sy(y);
if (LIBC_LIKELY(!sy.is_zero() && !sy.is_inf_or_nan() &&
!sx.is_inf_or_nan())) {
Expand Down
18 changes: 7 additions & 11 deletions libc/src/__support/FPUtil/generic/sqrt.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,19 +71,15 @@ LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, T> sqrt(T x) {
return x86::sqrt(x);
} else {
// IEEE floating points formats.
using Sign = fputil::Sign;
using FPBits_t = typename fputil::FPBits<T>;
using StorageType = typename FPBits_t::StorageType;
constexpr StorageType ONE = StorageType(1) << FPBits_t::FRACTION_LEN;
constexpr auto FLT_NAN =
FPBits_t::build_quiet_nan(Sign::POS, ONE >> 1).get_val();
using StorageType = typename FPBits<T>::StorageType;
constexpr StorageType ONE = StorageType(1) << FPBits<T>::FRACTION_LEN;

FPBits_t bits(x);
FPBits<T> bits(x);

if (bits.is_inf_or_nan()) {
if (bits.is_neg() && (bits.get_mantissa() == 0)) {
// sqrt(-Inf) = NaN
return FLT_NAN;
return FPBits<T>::build_quiet_nan(ONE >> 1);
} else {
// sqrt(NaN) = NaN
// sqrt(+Inf) = +Inf
Expand All @@ -95,7 +91,7 @@ LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, T> sqrt(T x) {
return x;
} else if (bits.is_neg()) {
// sqrt( negative numbers ) = NaN
return FLT_NAN;
return FPBits<T>::build_quiet_nan(ONE >> 1);
} else {
int x_exp = bits.get_exponent();
StorageType x_mant = bits.get_mantissa();
Expand Down Expand Up @@ -149,10 +145,10 @@ LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, T> sqrt(T x) {
}

// Remove hidden bit and append the exponent field.
x_exp = ((x_exp >> 1) + FPBits_t::EXP_BIAS);
x_exp = ((x_exp >> 1) + FPBits<T>::EXP_BIAS);

y = (y - ONE) |
(static_cast<StorageType>(x_exp) << FPBits_t::FRACTION_LEN);
(static_cast<StorageType>(x_exp) << FPBits<T>::FRACTION_LEN);

switch (quick_get_round()) {
case FE_TONEAREST:
Expand Down
8 changes: 3 additions & 5 deletions libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,14 @@ LIBC_INLINE long double sqrt(long double x);
LIBC_INLINE long double sqrt(long double x) {
using LDBits = FPBits<long double>;
using StorageType = typename LDBits::StorageType;
using Sign = fputil::Sign;
constexpr StorageType ONE = StorageType(1) << int(LDBits::FRACTION_LEN);
constexpr auto LDNAN = LDBits::build_quiet_nan(Sign::POS, ONE >> 1).get_val();

LDBits bits(x);
FPBits<long double> bits(x);

if (bits.is_inf_or_nan()) {
if (bits.is_neg() && (bits.get_mantissa() == 0)) {
// sqrt(-Inf) = NaN
return LDNAN;
return LDBits::build_quiet_nan(ONE >> 1);
} else {
// sqrt(NaN) = NaN
// sqrt(+Inf) = +Inf
Expand All @@ -59,7 +57,7 @@ LIBC_INLINE long double sqrt(long double x) {
return x;
} else if (bits.is_neg()) {
// sqrt( negative numbers ) = NaN
return LDNAN;
return LDBits::build_quiet_nan(ONE >> 1);
} else {
int x_exp = bits.get_explicit_exponent();
StorageType x_mant = bits.get_mantissa();
Expand Down
Loading

0 comments on commit b524eed

Please sign in to comment.