Skip to content

Commit 14f0c06

Browse files
authored
[libc] Fix is_subnormal for Intel Extended Precision (#78592)
Also turn a set of `get_biased_exponent() == 0` into `is_subnormal()` which is clearer.
1 parent 28d64c1 commit 14f0c06

File tree

7 files changed

+19
-34
lines changed

7 files changed

+19
-34
lines changed

libc/src/__support/FPUtil/FPBits.h

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -386,8 +386,11 @@ struct FPRepBase : public internal::FPLayout<fp_type> {
386386
bits = (value & FP_MASK);
387387
}
388388

389-
LIBC_INLINE constexpr bool is_zero() const {
390-
return (bits & EXP_SIG_MASK) == 0;
389+
LIBC_INLINE constexpr bool is_zero() const { return exp_sig_bits() == 0; }
390+
391+
LIBC_INLINE
392+
constexpr bool is_subnormal() const {
393+
return exp_bits() == encode(BiasedExponent::BITS_ALL_ZEROES());
391394
}
392395

393396
LIBC_INLINE constexpr bool is_neg() const { return sign().is_neg(); }
@@ -435,19 +438,11 @@ template <FPType fp_type> struct FPRep : public FPRepBase<fp_type> {
435438
return exp_sig_bits() ==
436439
encode(BiasedExponent::BITS_ALL_ONES(), Significand::ZERO());
437440
}
438-
LIBC_INLINE constexpr bool is_zero() const {
439-
return exp_sig_bits() ==
440-
encode(BiasedExponent::BITS_ALL_ZEROES(), Significand::ZERO());
441-
}
442441
LIBC_INLINE constexpr bool is_finite() const {
443442
return exp_bits() != encode(BiasedExponent::BITS_ALL_ONES());
444443
}
445-
LIBC_INLINE
446-
constexpr bool is_subnormal() const {
447-
return exp_bits() == encode(BiasedExponent::BITS_ALL_ZEROES());
448-
}
449444
LIBC_INLINE constexpr bool is_normal() const {
450-
return is_finite() && !is_subnormal();
445+
return is_finite() && !UP::is_subnormal();
451446
}
452447

453448
LIBC_INLINE static constexpr StorageType zero(Sign sign = Sign::POS) {
@@ -488,7 +483,7 @@ template <FPType fp_type> struct FPRep : public FPRepBase<fp_type> {
488483
// The function return mantissa with the implicit bit set iff the current
489484
// value is a valid normal number.
490485
LIBC_INLINE constexpr StorageType get_explicit_mantissa() {
491-
if (is_subnormal())
486+
if (UP::is_subnormal())
492487
return sig_bits();
493488
return (StorageType(1) << UP::SIG_LEN) | sig_bits();
494489
}
@@ -550,18 +545,9 @@ struct FPRep<FPType::X86_Binary80> : public FPRepBase<FPType::X86_Binary80> {
550545
return exp_sig_bits() ==
551546
encode(BiasedExponent::BITS_ALL_ONES(), Significand::MSB());
552547
}
553-
LIBC_INLINE constexpr bool is_zero() const {
554-
return exp_sig_bits() ==
555-
encode(BiasedExponent::BITS_ALL_ZEROES(), Significand::ZERO());
556-
}
557548
LIBC_INLINE constexpr bool is_finite() const {
558549
return !is_inf() && !is_nan();
559550
}
560-
LIBC_INLINE
561-
constexpr bool is_subnormal() const {
562-
return exp_sig_bits() >
563-
encode(BiasedExponent::BITS_ALL_ZEROES(), Significand::ZERO());
564-
}
565551
LIBC_INLINE constexpr bool is_normal() const {
566552
const auto exp = exp_bits();
567553
if (exp == encode(BiasedExponent::BITS_ALL_ZEROES()) ||

libc/src/__support/FPUtil/NormalFloat.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ template <typename T> struct NormalFloat {
153153
}
154154

155155
// Normalize subnormal numbers.
156-
if (bits.get_biased_exponent() == 0) {
156+
if (bits.is_subnormal()) {
157157
unsigned shift = evaluate_normalization_shift(bits.get_mantissa());
158158
mantissa = StorageType(bits.get_mantissa()) << shift;
159159
exponent = 1 - FPBits<T>::EXP_BIAS - shift;
@@ -186,7 +186,7 @@ NormalFloat<long double>::init_from_bits(FPBits<long double> bits) {
186186
return;
187187
}
188188

189-
if (bits.get_biased_exponent() == 0) {
189+
if (bits.is_subnormal()) {
190190
if (bits.get_implicit_bit() == 0) {
191191
// Since we ignore zero value, the mantissa in this case is non-zero.
192192
int normalization_shift =

libc/src/__support/FPUtil/generic/FMA.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,15 +104,15 @@ template <> LIBC_INLINE double fma<double>(double x, double y, double z) {
104104
int z_exp = 0;
105105

106106
// Normalize denormal inputs.
107-
if (LIBC_UNLIKELY(FPBits(x).get_biased_exponent() == 0)) {
107+
if (LIBC_UNLIKELY(FPBits(x).is_subnormal())) {
108108
x_exp -= 52;
109109
x *= 0x1.0p+52;
110110
}
111-
if (LIBC_UNLIKELY(FPBits(y).get_biased_exponent() == 0)) {
111+
if (LIBC_UNLIKELY(FPBits(y).is_subnormal())) {
112112
y_exp -= 52;
113113
y *= 0x1.0p+52;
114114
}
115-
if (LIBC_UNLIKELY(FPBits(z).get_biased_exponent() == 0)) {
115+
if (LIBC_UNLIKELY(FPBits(z).is_subnormal())) {
116116
z_exp -= 52;
117117
z *= 0x1.0p+52;
118118
}

libc/src/__support/FPUtil/generic/sqrt.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, T> sqrt(T x) {
9797
StorageType x_mant = bits.get_mantissa();
9898

9999
// Step 1a: Normalize denormal input and append hidden bit to the mantissa
100-
if (bits.get_biased_exponent() == 0) {
100+
if (bits.is_subnormal()) {
101101
++x_exp; // let x_exp be the correct exponent of ONE bit.
102102
internal::normalize<T>(x_exp, x_mant);
103103
} else {

libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ LIBC_INLINE long double sqrt(long double x) {
6565
// Step 1a: Normalize denormal input
6666
if (bits.get_implicit_bit()) {
6767
x_mant |= ONE;
68-
} else if (bits.get_biased_exponent() == 0) {
68+
} else if (bits.is_subnormal()) {
6969
normalize(x_exp, x_mant);
7070
}
7171

libc/src/__support/FPUtil/x86_64/NextAfterLongDouble.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@ LIBC_INLINE long double nextafter(long double from, long double to) {
3838
return to;
3939

4040
// Convert pseudo subnormal number to normal number.
41-
if (from_bits.get_implicit_bit() == 1 &&
42-
from_bits.get_biased_exponent() == 0) {
41+
if (from_bits.get_implicit_bit() == 1 && from_bits.is_subnormal()) {
4342
from_bits.set_biased_exponent(1);
4443
}
4544

libc/utils/MPFRWrapper/MPFRUtils.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -457,9 +457,9 @@ class MPFRNumber {
457457
int thisExponent = FPBits<T>(thisAsT).get_exponent();
458458
int inputExponent = FPBits<T>(input).get_exponent();
459459
// Adjust the exponents for denormal numbers.
460-
if (FPBits<T>(thisAsT).get_biased_exponent() == 0)
460+
if (FPBits<T>(thisAsT).is_subnormal())
461461
++thisExponent;
462-
if (FPBits<T>(input).get_biased_exponent() == 0)
462+
if (FPBits<T>(input).is_subnormal())
463463
++inputExponent;
464464

465465
if (thisAsT * input < 0 || thisExponent == inputExponent) {
@@ -481,9 +481,9 @@ class MPFRNumber {
481481
int minExponent = FPBits<T>(min).get_exponent();
482482
int maxExponent = FPBits<T>(max).get_exponent();
483483
// Adjust the exponents for denormal numbers.
484-
if (FPBits<T>(min).get_biased_exponent() == 0)
484+
if (FPBits<T>(min).is_subnormal())
485485
++minExponent;
486-
if (FPBits<T>(max).get_biased_exponent() == 0)
486+
if (FPBits<T>(max).is_subnormal())
487487
++maxExponent;
488488

489489
MPFRNumber minMPFR(min);

0 commit comments

Comments
 (0)