Skip to content

Commit

Permalink
[libc][NFC] Remove FPBits cast operator (#79142)
Browse files Browse the repository at this point in the history
The semantics for casting can range from "bitcast" (same representation)
to "different representation", to "type promotion". Here we remove the
cast operator and force usage of `get_val` as the only function to get
the floating point value, making the intent clearer and more consistent.
  • Loading branch information
gchatelet authored Jan 23, 2024
1 parent e1aa5b1 commit 2856db0
Show file tree
Hide file tree
Showing 102 changed files with 366 additions and 369 deletions.
2 changes: 1 addition & 1 deletion libc/src/__support/FPUtil/BasicOperations.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ 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(Sign::POS);
return T(bits);
return bits.get_val();
}

template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
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 @@ -86,7 +86,7 @@ LIBC_INLINE T remquo(T x, T y, int &q) {
// then the conversion to native remainder value should be updated
// appropriately and some directed tests added.
T native_remainder(remainder);
T absy = T(ybits);
T absy = ybits.get_val();
int cmp = remainder.mul2(1).cmp(normaly);
if (cmp > 0) {
q = q + 1;
Expand Down
2 changes: 0 additions & 2 deletions libc/src/__support/FPUtil/FPBits.h
Original file line number Diff line number Diff line change
Expand Up @@ -727,8 +727,6 @@ struct FPBits final : public internal::FPRep<get_fp_type<T>(), FPBits<T>> {
// Floating-point conversions.
LIBC_INLINE constexpr T get_val() const { return cpp::bit_cast<T>(bits); }

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

// 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
10 changes: 5 additions & 5 deletions libc/src/__support/FPUtil/Hypot.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ LIBC_INLINE T hypot(T x, T y) {
FPBits_t x_bits(x), y_bits(y);

if (x_bits.is_inf() || y_bits.is_inf()) {
return T(FPBits_t::inf());
return FPBits_t::inf().get_val();
}
if (x_bits.is_nan()) {
return x;
Expand Down Expand Up @@ -196,8 +196,8 @@ LIBC_INLINE T hypot(T x, T y) {
if (out_exp >= FPBits_t::MAX_BIASED_EXPONENT) {
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 FPBits_t::inf().get_val();
return FPBits_t::max_normal().get_val();
}
} else {
// For denormal result, we simply move the leading bit of the result to
Expand Down Expand Up @@ -253,8 +253,8 @@ LIBC_INLINE T hypot(T x, T y) {
++out_exp;
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 FPBits_t::inf().get_val();
return FPBits_t::max_normal().get_val();
}
}

Expand Down
14 changes: 7 additions & 7 deletions libc/src/__support/FPUtil/ManipulationFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@ LIBC_INLINE T modf(T x, T &iptr) {
return x;
} else if (bits.is_inf()) {
iptr = x;
return T(FPBits<T>::zero(bits.sign()));
return FPBits<T>::zero(bits.sign()).get_val();
} else {
iptr = trunc(x);
if (x == iptr) {
// If x is already an integer value, then return zero with the right
// sign.
return T(FPBits<T>::zero(bits.sign()));
return FPBits<T>::zero(bits.sign()).get_val();
} else {
return x - iptr;
}
Expand All @@ -66,7 +66,7 @@ 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).sign());
return T(xbits);
return xbits.get_val();
}

template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
Expand Down Expand Up @@ -103,12 +103,12 @@ LIBC_INLINE T logb(T x) {
if (bits.is_zero()) {
// TODO(Floating point exception): Raise div-by-zero exception.
// TODO(errno): POSIX requires setting errno to ERANGE.
return T(FPBits<T>::inf(Sign::NEG));
return FPBits<T>::inf(Sign::NEG).get_val();
} else if (bits.is_nan()) {
return x;
} else if (bits.is_inf()) {
// Return positive infinity.
return T(FPBits<T>::inf());
return FPBits<T>::inf().get_val();
}

NormalFloat<T> normal(bits);
Expand All @@ -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 T(FPBits<T>::inf(bits.sign()));
return FPBits<T>::inf(bits.sign()).get_val();

// Similarly on the negative side we return zero early if |exp| is too small.
if (exp < -exp_limit)
return T(FPBits<T>::zero(bits.sign()));
return FPBits<T>::zero(bits.sign()).get_val();

// For all other values, NormalFloat to T conversion handles it the right way.
NormalFloat<T> normal(bits);
Expand Down
14 changes: 7 additions & 7 deletions libc/src/__support/FPUtil/NearestIntegerOperations.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ LIBC_INLINE T trunc(T x) {

// If the exponent is such that abs(x) is less than 1, then return 0.
if (exponent <= -1)
return T(FPBits<T>::zero(bits.sign()));
return FPBits<T>::zero(bits.sign()).get_val();

int trim_size = FPBits<T>::FRACTION_LEN - exponent;
bits.set_mantissa((bits.get_mantissa() >> trim_size) << trim_size);
return T(bits);
return bits.get_val();
}

template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
Expand Down Expand Up @@ -73,7 +73,7 @@ LIBC_INLINE T ceil(T x) {

uint32_t trim_size = FPBits<T>::FRACTION_LEN - exponent;
bits.set_mantissa((bits.get_mantissa() >> trim_size) << trim_size);
T trunc_value = T(bits);
T trunc_value = bits.get_val();

// If x is already an integer, return it.
if (trunc_value == x)
Expand Down Expand Up @@ -114,19 +114,19 @@ LIBC_INLINE T round(T x) {

if (exponent == -1) {
// Absolute value of x is greater than equal to 0.5 but less than 1.
return T(FPBits<T>::one(bits.sign()));
return FPBits<T>::one(bits.sign()).get_val();
}

if (exponent <= -2) {
// Absolute value of x is less than 0.5.
return T(FPBits<T>::zero(bits.sign()));
return FPBits<T>::zero(bits.sign()).get_val();
}

uint32_t trim_size = FPBits<T>::FRACTION_LEN - exponent;
bool half_bit_set =
bool(bits.get_mantissa() & (StorageType(1) << (trim_size - 1)));
bits.set_mantissa((bits.get_mantissa() >> trim_size) << trim_size);
T trunc_value = T(bits);
T trunc_value = bits.get_val();

// If x is already an integer, return it.
if (trunc_value == x)
Expand Down Expand Up @@ -180,7 +180,7 @@ LIBC_INLINE T round_using_current_rounding_mode(T x) {
uint32_t trim_size = FPBits<T>::FRACTION_LEN - exponent;
FPBits<T> new_bits = bits;
new_bits.set_mantissa((bits.get_mantissa() >> trim_size) << trim_size);
T trunc_value = T(new_bits);
T trunc_value = new_bits.get_val();

// If x is already an integer, return it.
if (trunc_value == x)
Expand Down
14 changes: 7 additions & 7 deletions libc/src/__support/FPUtil/NormalFloat.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,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 T(FPBits<T>::inf(sign));
return FPBits<T>::inf(sign).get_val();
}

FPBits<T> result(T(0.0));
Expand Down Expand Up @@ -129,15 +129,15 @@ template <typename T> struct NormalFloat {
// the overflow into the exponent.
if (new_mantissa == ONE)
result.set_biased_exponent(1);
return T(result);
return result.get_val();
} else {
return T(result);
return result.get_val();
}
}

result.set_biased_exponent(exponent + FPBits<T>::EXP_BIAS);
result.set_mantissa(mantissa);
return T(result);
return result.get_val();
}

private:
Expand Down Expand Up @@ -250,16 +250,16 @@ template <> LIBC_INLINE NormalFloat<long double>::operator long double() const {
} else {
result.set_implicit_bit(0);
}
return static_cast<long double>(result);
return result.get_val();
} else {
return static_cast<long double>(result);
return result.get_val();
}
}

result.set_biased_exponent(biased_exponent);
result.set_mantissa(mantissa);
result.set_implicit_bit(1);
return static_cast<long double>(result);
return result.get_val();
}
#endif // LIBC_LONG_DOUBLE_IS_X86_FLOAT80

Expand Down
8 changes: 4 additions & 4 deletions libc/src/__support/FPUtil/generic/FMA.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ template <> LIBC_INLINE float fma<float>(float x, float y, float z) {
// correct (when it matters).
fputil::FPBits<double> t(
(bit_prod.get_biased_exponent() >= bitz.get_biased_exponent())
? ((double(bit_sum) - double(bit_prod)) - double(bitz))
: ((double(bit_sum) - double(bitz)) - double(bit_prod)));
? ((bit_sum.get_val() - bit_prod.get_val()) - bitz.get_val())
: ((bit_sum.get_val() - bitz.get_val()) - bit_prod.get_val()));

// Update sticky bits if t != 0.0 and the least (52 - 23 - 1 = 28) bits are
// zero.
Expand All @@ -72,7 +72,7 @@ template <> LIBC_INLINE float fma<float>(float x, float y, float z) {
}
}

return static_cast<float>(static_cast<double>(bit_sum));
return static_cast<float>(bit_sum.get_val());
}

namespace internal {
Expand Down Expand Up @@ -257,7 +257,7 @@ template <> LIBC_INLINE double fma<double>(double x, double y, double z) {
(round_mode == FE_DOWNWARD && prod_sign.is_pos())) {
return FPBits::max_normal(prod_sign).get_val();
}
return static_cast<double>(FPBits::inf(prod_sign));
return FPBits::inf(prod_sign).get_val();
}

// Remove hidden bit and append the exponent field and sign bit.
Expand Down
8 changes: 4 additions & 4 deletions libc/src/__support/str_to_float.h
Original file line number Diff line number Diff line change
Expand Up @@ -568,11 +568,11 @@ clinger_fast_path(ExpandedFloat<T> init_num,
ClingerConsts<T>::POWERS_OF_TEN_ARRAY[exp10]);

// If the results are equal, then we don't need to use the rounding mode.
if (T(result) != -T(negative_result)) {
if (result.get_val() != -negative_result.get_val()) {
FPBits lower_result;
FPBits higher_result;

if (T(result) < -T(negative_result)) {
if (result.get_val() < -negative_result.get_val()) {
lower_result = result;
higher_result = negative_result;
} else {
Expand Down Expand Up @@ -1194,7 +1194,7 @@ LIBC_INLINE StrToNumResult<T> strtofloatingpoint(const char *__restrict src) {
// special 80 bit long doubles. Otherwise it should be inlined out.
set_implicit_bit<T>(result);

return {T(result), index, error};
return {result.get_val(), index, error};
}

template <class T> LIBC_INLINE StrToNumResult<T> strtonan(const char *arg) {
Expand All @@ -1216,7 +1216,7 @@ template <class T> LIBC_INLINE StrToNumResult<T> strtonan(const char *arg) {
}

result = FPBits::build_quiet_nan(fputil::Sign::POS, nan_mantissa);
return {T(result), 0, error};
return {result.get_val(), 0, error};
}

} // namespace internal
Expand Down
2 changes: 1 addition & 1 deletion libc/src/math/generic/exp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ double set_exceptional(double x) {
fputil::raise_except_if_required(FE_OVERFLOW);
}
// x is +inf or nan
return x + static_cast<double>(FPBits::inf());
return x + FPBits::inf().get_val();
}

} // namespace
Expand Down
2 changes: 1 addition & 1 deletion libc/src/math/generic/exp10.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ double set_exceptional(double x) {
fputil::raise_except_if_required(FE_OVERFLOW);
}
// x is +inf or nan
return x + static_cast<double>(FPBits::inf());
return x + FPBits::inf().get_val();
}

} // namespace
Expand Down
2 changes: 1 addition & 1 deletion libc/src/math/generic/exp2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ double set_exceptional(double x) {
fputil::raise_except_if_required(FE_OVERFLOW);
}
// x is +inf or nan
return x + static_cast<double>(FPBits::inf());
return x + FPBits::inf().get_val();
}

} // namespace
Expand Down
2 changes: 1 addition & 1 deletion libc/src/math/generic/expf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ LLVM_LIBC_FUNCTION(float, expf, (float x)) {
fputil::raise_except_if_required(FE_OVERFLOW);
}
// x is +inf or nan
return x + static_cast<float>(FPBits::inf());
return x + FPBits::inf().get_val();
}
}
// For -104 < x < 89, to compute exp(x), we perform the following range
Expand Down
6 changes: 3 additions & 3 deletions libc/src/math/generic/hypotf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ LLVM_LIBC_FUNCTION(float, hypotf, (float x, float y)) {

if (!DoubleBits(sum_sq).is_inf_or_nan()) {
// Correct rounding.
double r_sq = static_cast<double>(result) * static_cast<double>(result);
double r_sq = result.get_val() * result.get_val();
double diff = sum_sq - r_sq;
constexpr uint64_t mask = 0x0000'0000'3FFF'FFFFULL;
uint64_t lrs = result.uintval() & mask;
Expand All @@ -60,14 +60,14 @@ LLVM_LIBC_FUNCTION(float, hypotf, (float x, float y)) {
FPBits bits_x(x), bits_y(y);
if (bits_x.is_inf_or_nan() || bits_y.is_inf_or_nan()) {
if (bits_x.is_inf() || bits_y.is_inf())
return static_cast<float>(FPBits::inf());
return FPBits::inf().get_val();
if (bits_x.is_nan())
return x;
return y;
}
}

return static_cast<float>(static_cast<double>(result));
return static_cast<float>(result.get_val());
}

} // namespace LIBC_NAMESPACE
2 changes: 1 addition & 1 deletion libc/src/math/generic/log10f.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ LLVM_LIBC_FUNCTION(float, log10f, (float x)) {
// Set bits to 1.m
xbits.set_biased_exponent(0x7F);

float u = static_cast<float>(xbits);
float u = xbits.get_val();
double v;
#ifdef LIBC_TARGET_CPU_HAS_FMA
v = static_cast<double>(fputil::multiply_add(u, R[index], -1.0f)); // Exact.
Expand Down
4 changes: 2 additions & 2 deletions libc/src/math/generic/log1pf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ LIBC_INLINE float log(double x) {
// Clear the lowest 45 bits.
f.bits &= ~0x0000'1FFF'FFFF'FFFFULL;

double d = static_cast<double>(xbits) - static_cast<double>(f);
double d = xbits.get_val() - f.get_val();
d *= ONE_OVER_F[f_index];

double extra_factor = fputil::multiply_add(m, LOG_2, LOG_F[f_index]);
Expand Down Expand Up @@ -106,7 +106,7 @@ LLVM_LIBC_FUNCTION(float, log1pf, (float x)) {
case 0xbf800000U: // x = -1.0
fputil::set_errno_if_required(ERANGE);
fputil::raise_except_if_required(FE_DIVBYZERO);
return static_cast<float>(fputil::FPBits<float>::inf(fputil::Sign::NEG));
return FPBits::inf(fputil::Sign::NEG).get_val();
#ifndef LIBC_TARGET_CPU_HAS_FMA
case 0x4cc1c80bU: // x = 0x1.839016p+26f
return fputil::round_result_slightly_down(0x1.26fc04p+4f);
Expand Down
2 changes: 1 addition & 1 deletion libc/src/math/generic/log2f.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ LLVM_LIBC_FUNCTION(float, log2f, (float x)) {
// Set bits to 1.m
xbits.set_biased_exponent(0x7F);

float u = static_cast<float>(xbits);
float u = xbits.get_val();
double v;
#ifdef LIBC_TARGET_CPU_HAS_FMA
v = static_cast<double>(fputil::multiply_add(u, R[index], -1.0f)); // Exact.
Expand Down
4 changes: 2 additions & 2 deletions libc/src/math/generic/logf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ LLVM_LIBC_FUNCTION(float, logf, (float x)) {
// Return -inf and raise FE_DIVBYZERO
fputil::set_errno_if_required(ERANGE);
fputil::raise_except_if_required(FE_DIVBYZERO);
return static_cast<float>(FPBits::inf(fputil::Sign::NEG));
return FPBits::inf(Sign::NEG).get_val();
}
// Normalize denormal inputs.
xbits = FPBits(xbits.get_val() * 0x1.0p23f);
Expand Down Expand Up @@ -149,7 +149,7 @@ LLVM_LIBC_FUNCTION(float, logf, (float x)) {
// Set bits to 1.m
xbits.set_biased_exponent(0x7F);

float u = static_cast<float>(xbits);
float u = xbits.get_val();
double v;
#ifdef LIBC_TARGET_CPU_HAS_FMA
v = static_cast<double>(fputil::multiply_add(u, R[index], -1.0f)); // Exact.
Expand Down
Loading

0 comments on commit 2856db0

Please sign in to comment.