[libc-commits] [libc] b03567f - [libc][math] Improved FBits performance and readablity.
Kirill Okhotnikov via libc-commits
libc-commits at lists.llvm.org
Fri Jun 10 01:21:55 PDT 2022
Author: Kirill Okhotnikov
Date: 2022-06-10T10:21:44+02:00
New Revision: b03567fe2b74ea777bf134d4c1d7b76746fc7dd9
URL: https://github.com/llvm/llvm-project/commit/b03567fe2b74ea777bf134d4c1d7b76746fc7dd9
DIFF: https://github.com/llvm/llvm-project/commit/b03567fe2b74ea777bf134d4c1d7b76746fc7dd9.diff
LOG: [libc][math] Improved FBits performance and readablity.
Some function added in preparation to fmod commit.
Differential Revision: https://reviews.llvm.org/D127097
Added:
Modified:
libc/src/__support/FPUtil/FPBits.h
libc/src/__support/FPUtil/FloatProperties.h
Removed:
################################################################################
diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index 36df9c54c4777..6743fee9b1a48 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -57,6 +57,11 @@ template <typename T> struct FPBits {
UIntType get_mantissa() const { return bits & FloatProp::MANTISSA_MASK; }
+ // The function return mantissa with implicit bit set for normal values.
+ constexpr UIntType get_explicit_mantissa() {
+ return (FloatProp::MANTISSA_MASK + 1) | (FloatProp::MANTISSA_MASK & bits);
+ }
+
void set_unbiased_exponent(UIntType expVal) {
expVal = (expVal << (FloatProp::MANTISSA_WIDTH)) & FloatProp::EXPONENT_MASK;
bits &= ~(FloatProp::EXPONENT_MASK);
@@ -69,14 +74,12 @@ template <typename T> struct FPBits {
}
void set_sign(bool signVal) {
- bits &= ~(FloatProp::SIGN_MASK);
- UIntType sign = UIntType(signVal) << (FloatProp::BIT_WIDTH - 1);
- bits |= sign;
+ bits |= FloatProp::SIGN_MASK;
+ if (!signVal)
+ bits -= FloatProp::SIGN_MASK;
}
- bool get_sign() const {
- return ((bits & FloatProp::SIGN_MASK) >> (FloatProp::BIT_WIDTH - 1));
- }
+ bool get_sign() const { return (bits & FloatProp::SIGN_MASK) != 0; }
static_assert(sizeof(T) == sizeof(UIntType),
"Data type and integral representation have
diff erent sizes.");
@@ -92,7 +95,7 @@ template <typename T> struct FPBits {
static constexpr UIntType MAX_NORMAL =
((UIntType(MAX_EXPONENT) - 1) << MantissaWidth<T>::VALUE) | MAX_SUBNORMAL;
- // We don't want accidental type promotions/conversions so we require exact
+ // We don't want accidental type promotions/conversions, so we require exact
// type match.
template <typename XType,
cpp::EnableIfType<cpp::IsSame<T, XType>::Value, int> = 0>
@@ -118,38 +121,41 @@ template <typename T> struct FPBits {
}
bool is_zero() const {
- return get_mantissa() == 0 && get_unbiased_exponent() == 0;
+ // Remove sign bit by shift
+ return (bits << 1) == 0;
}
bool is_inf() const {
- return get_mantissa() == 0 && get_unbiased_exponent() == MAX_EXPONENT;
+ return (bits & FloatProp::EXP_MANT_MASK) == FloatProp::EXPONENT_MASK;
}
bool is_nan() const {
- return get_unbiased_exponent() == MAX_EXPONENT && get_mantissa() != 0;
+ return (bits & FloatProp::EXP_MANT_MASK) > FloatProp::EXPONENT_MASK;
}
- bool is_inf_or_nan() const { return get_unbiased_exponent() == MAX_EXPONENT; }
-
- static FPBits<T> zero() { return FPBits(); }
+ bool is_inf_or_nan() const {
+ return (bits & FloatProp::EXPONENT_MASK) == FloatProp::EXPONENT_MASK;
+ }
- static FPBits<T> neg_zero() {
- return FPBits(UIntType(1) << (sizeof(UIntType) * 8 - 1));
+ static constexpr FPBits<T> zero(bool sign = false) {
+ return FPBits(sign ? FloatProp::SIGN_MASK : UIntType(0));
}
- static FPBits<T> inf() {
+ static constexpr FPBits<T> neg_zero() { return zero(true); }
+
+ static constexpr FPBits<T> inf() {
FPBits<T> bits;
bits.set_unbiased_exponent(MAX_EXPONENT);
return bits;
}
- static FPBits<T> neg_inf() {
+ static constexpr FPBits<T> neg_inf() {
FPBits<T> bits = inf();
bits.set_sign(1);
return bits;
}
- static T build_nan(UIntType v) {
+ static constexpr T build_nan(UIntType v) {
FPBits<T> bits = inf();
bits.set_mantissa(v);
return T(bits);
diff --git a/libc/src/__support/FPUtil/FloatProperties.h b/libc/src/__support/FPUtil/FloatProperties.h
index 8cf0da1267a91..ad52a4066e1e6 100644
--- a/libc/src/__support/FPUtil/FloatProperties.h
+++ b/libc/src/__support/FPUtil/FloatProperties.h
@@ -22,7 +22,7 @@ template <> struct FloatProperties<float> {
static_assert(sizeof(BitsType) == sizeof(float),
"Unexpected size of 'float' type.");
- static constexpr uint32_t BIT_WIDTH = sizeof(BitsType) << 3;
+ static constexpr uint32_t BIT_WIDTH = sizeof(BitsType) * 8;
static constexpr uint32_t MANTISSA_WIDTH = 23;
static constexpr uint32_t EXPONENT_WIDTH = 8;
@@ -32,6 +32,10 @@ template <> struct FloatProperties<float> {
static constexpr BitsType EXPONENT_MASK = ~(SIGN_MASK | MANTISSA_MASK);
static constexpr uint32_t EXPONENT_BIAS = 127;
+ static constexpr BitsType EXP_MANT_MASK = MANTISSA_MASK + EXPONENT_MASK;
+ static_assert(EXP_MANT_MASK == ~SIGN_MASK,
+ "Exponent and mantissa masks are not as expected.");
+
// If a number x is a NAN, then it is a quiet NAN if:
// QuietNaNMask & bits(x) != 0
// Else, it is a signalling NAN.
@@ -43,7 +47,7 @@ template <> struct FloatProperties<double> {
static_assert(sizeof(BitsType) == sizeof(double),
"Unexpected size of 'double' type.");
- static constexpr uint32_t BIT_WIDTH = sizeof(BitsType) << 3;
+ static constexpr uint32_t BIT_WIDTH = sizeof(BitsType) * 8;
static constexpr uint32_t MANTISSA_WIDTH = 52;
static constexpr uint32_t EXPONENT_WIDTH = 11;
@@ -53,6 +57,10 @@ template <> struct FloatProperties<double> {
static constexpr BitsType EXPONENT_MASK = ~(SIGN_MASK | MANTISSA_MASK);
static constexpr uint32_t EXPONENT_BIAS = 1023;
+ static constexpr BitsType EXP_MANT_MASK = MANTISSA_MASK + EXPONENT_MASK;
+ static_assert(EXP_MANT_MASK == ~SIGN_MASK,
+ "Exponent and mantissa masks are not as expected.");
+
// If a number x is a NAN, then it is a quiet NAN if:
// QuietNaNMask & bits(x) != 0
// Else, it is a signalling NAN.
@@ -95,7 +103,7 @@ template <> struct FloatProperties<long double> {
static_assert(sizeof(BitsType) == sizeof(long double),
"Unexpected size of 'long double' type.");
- static constexpr uint32_t BIT_WIDTH = (sizeof(BitsType) << 3) - 48;
+ static constexpr uint32_t BIT_WIDTH = (sizeof(BitsType) * 8) - 48;
static constexpr uint32_t MANTISSA_WIDTH = 63;
static constexpr uint32_t EXPONENT_WIDTH = 15;
More information about the libc-commits
mailing list