[libc-commits] [libc] [libc] `FPRep` builders return `FPRep` instead of raw `StorageType` (PR #78588)
Guillaume Chatelet via libc-commits
libc-commits at lists.llvm.org
Thu Jan 18 06:43:18 PST 2024
https://github.com/gchatelet created https://github.com/llvm/llvm-project/pull/78588
None
>From 49ba96c8aa51fb56a5bf96a1e97fef48bcc42f09 Mon Sep 17 00:00:00 2001
From: Guillaume Chatelet <gchatelet at google.com>
Date: Thu, 18 Jan 2024 14:42:54 +0000
Subject: [PATCH] [libc] `FPRep` builders return `FPRep` instead of raw
`StorageType`
---
libc/src/__support/FPUtil/FPBits.h | 68 ++++----
.../test/src/__support/FPUtil/fpbits_test.cpp | 163 +++++++++---------
2 files changed, 120 insertions(+), 111 deletions(-)
diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index 3ee6289b749648..5df49350e3744e 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -332,7 +332,10 @@ struct FPRepBase : public internal::FPLayout<fp_type> {
mask_trailing_ones<StorageType, FRACTION_LEN>();
// The floating point number representation as an unsigned integer.
- StorageType bits = 0;
+ StorageType bits;
+
+ LIBC_INLINE constexpr FPRepBase() : bits(0) {}
+ LIBC_INLINE constexpr FPRepBase(StorageType value) : bits(value) {}
public:
LIBC_INLINE constexpr Sign sign() const {
@@ -418,6 +421,7 @@ template <FPType fp_type> struct FPRep : public FPRepBase<fp_type> {
using UP::exp_bits;
using UP::exp_sig_bits;
using UP::sig_bits;
+ using UP::UP;
public:
LIBC_INLINE constexpr bool is_nan() const {
@@ -450,37 +454,35 @@ template <FPType fp_type> struct FPRep : public FPRepBase<fp_type> {
return is_finite() && !is_subnormal();
}
- LIBC_INLINE static constexpr StorageType zero(Sign sign = Sign::POS) {
+ LIBC_INLINE static constexpr FPRep zero(Sign sign = Sign::POS) {
return encode(sign, BiasedExponent::BITS_ALL_ZEROES(), Significand::ZERO());
}
- LIBC_INLINE static constexpr StorageType one(Sign sign = Sign::POS) {
+ LIBC_INLINE static constexpr FPRep one(Sign sign = Sign::POS) {
return encode(sign, Exponent::ZERO(), Significand::ZERO());
}
- LIBC_INLINE static constexpr StorageType
- min_subnormal(Sign sign = Sign::POS) {
+ LIBC_INLINE static constexpr FPRep min_subnormal(Sign sign = Sign::POS) {
return encode(sign, BiasedExponent::BITS_ALL_ZEROES(), Significand::LSB());
}
- LIBC_INLINE static constexpr StorageType
- max_subnormal(Sign sign = Sign::POS) {
+ LIBC_INLINE static constexpr FPRep max_subnormal(Sign sign = Sign::POS) {
return encode(sign, BiasedExponent::BITS_ALL_ZEROES(),
Significand::BITS_ALL_ONES());
}
- LIBC_INLINE static constexpr StorageType min_normal(Sign sign = Sign::POS) {
+ LIBC_INLINE static constexpr FPRep min_normal(Sign sign = Sign::POS) {
return encode(sign, Exponent::MIN(), Significand::ZERO());
}
- LIBC_INLINE static constexpr StorageType max_normal(Sign sign = Sign::POS) {
+ LIBC_INLINE static constexpr FPRep max_normal(Sign sign = Sign::POS) {
return encode(sign, Exponent::MAX(), Significand::BITS_ALL_ONES());
}
- LIBC_INLINE static constexpr StorageType inf(Sign sign = Sign::POS) {
+ LIBC_INLINE static constexpr FPRep inf(Sign sign = Sign::POS) {
return encode(sign, BiasedExponent::BITS_ALL_ONES(), Significand::ZERO());
}
- LIBC_INLINE static constexpr StorageType build_nan(Sign sign = Sign::POS,
- StorageType v = 0) {
+ LIBC_INLINE static constexpr FPRep 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(Sign sign = Sign::POS, StorageType v = 0) {
+ LIBC_INLINE static constexpr FPRep build_quiet_nan(Sign sign = Sign::POS,
+ StorageType v = 0) {
return encode(sign, BiasedExponent::BITS_ALL_ONES(),
Significand::MSB() | Significand(v));
}
@@ -507,6 +509,7 @@ struct FPRep<FPType::X86_Binary80> : public FPRepBase<FPType::X86_Binary80> {
using typename UP::BiasedExponent;
using typename UP::Significand;
using UP::encode;
+ using UP::UP;
public:
// The x86 80 bit float represents the leading digit of the mantissa
@@ -570,38 +573,36 @@ struct FPRep<FPType::X86_Binary80> : public FPRepBase<FPType::X86_Binary80> {
return get_implicit_bit();
}
- LIBC_INLINE static constexpr StorageType zero(Sign sign = Sign::POS) {
+ LIBC_INLINE static constexpr FPRep zero(Sign sign = Sign::POS) {
return encode(sign, BiasedExponent::BITS_ALL_ZEROES(), Significand::ZERO());
}
- LIBC_INLINE static constexpr StorageType one(Sign sign = Sign::POS) {
+ LIBC_INLINE static constexpr FPRep one(Sign sign = Sign::POS) {
return encode(sign, Exponent::ZERO(), Significand::MSB());
}
- LIBC_INLINE static constexpr StorageType
- min_subnormal(Sign sign = Sign::POS) {
+ LIBC_INLINE static constexpr FPRep min_subnormal(Sign sign = Sign::POS) {
return encode(sign, BiasedExponent::BITS_ALL_ZEROES(), Significand::LSB());
}
- LIBC_INLINE static constexpr StorageType
- max_subnormal(Sign sign = Sign::POS) {
+ LIBC_INLINE static constexpr FPRep 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(Sign sign = Sign::POS) {
+ LIBC_INLINE static constexpr FPRep min_normal(Sign sign = Sign::POS) {
return encode(sign, Exponent::MIN(), Significand::MSB());
}
- LIBC_INLINE static constexpr StorageType max_normal(Sign sign = Sign::POS) {
+ LIBC_INLINE static constexpr FPRep max_normal(Sign sign = Sign::POS) {
return encode(sign, Exponent::MAX(), Significand::BITS_ALL_ONES());
}
- LIBC_INLINE static constexpr StorageType inf(Sign sign = Sign::POS) {
+ LIBC_INLINE static constexpr FPRep inf(Sign sign = Sign::POS) {
return encode(sign, BiasedExponent::BITS_ALL_ONES(), Significand::MSB());
}
- LIBC_INLINE static constexpr StorageType build_nan(Sign sign = Sign::POS,
- StorageType v = 0) {
+ LIBC_INLINE static constexpr FPRep 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(Sign sign = Sign::POS, StorageType v = 0) {
+ LIBC_INLINE static constexpr FPRep build_quiet_nan(Sign sign = Sign::POS,
+ StorageType v = 0) {
return encode(sign, BiasedExponent::BITS_ALL_ONES(),
Significand::MSB() | (Significand::MSB() >> 1) |
Significand(v));
@@ -671,14 +672,15 @@ template <typename T> struct FPBits : public internal::FPRep<get_fp_type<T>()> {
using UP::bits;
using UP::EXP_LEN;
- using UP::UP;
// Constants.
static constexpr int MAX_BIASED_EXPONENT = (1 << EXP_LEN) - 1;
- 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);
+ static constexpr StorageType MIN_NORMAL = UP::min_normal(Sign::POS).uintval();
+ static constexpr StorageType MAX_NORMAL = UP::max_normal(Sign::POS).uintval();
+ static constexpr StorageType MIN_SUBNORMAL =
+ UP::min_subnormal(Sign::POS).uintval();
+ static constexpr StorageType MAX_SUBNORMAL =
+ UP::max_subnormal(Sign::POS).uintval();
// Constructors.
LIBC_INLINE constexpr FPBits() = default;
@@ -687,6 +689,8 @@ template <typename T> struct FPBits : public internal::FPRep<get_fp_type<T>()> {
using Unqual = typename cpp::remove_cv_t<XType>;
if constexpr (cpp::is_same_v<Unqual, T>) {
bits = cpp::bit_cast<StorageType>(x);
+ } else if constexpr (cpp::is_same_v<Unqual, UP>) {
+ bits = x.uintval();
} else if constexpr (cpp::is_same_v<Unqual, StorageType>) {
bits = x;
} else {
diff --git a/libc/test/src/__support/FPUtil/fpbits_test.cpp b/libc/test/src/__support/FPUtil/fpbits_test.cpp
index f0b155085dabf5..8f062da6bf5963 100644
--- a/libc/test/src/__support/FPUtil/fpbits_test.cpp
+++ b/libc/test/src/__support/FPUtil/fpbits_test.cpp
@@ -13,21 +13,23 @@
using LIBC_NAMESPACE::fputil::FPBits;
using LIBC_NAMESPACE::fputil::Sign;
+#define EXPECT_REP_EQ(A, REP) EXPECT_EQ(A, REP.uintval())
+
TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary16) {
using LIBC_NAMESPACE::fputil::FPType;
using LIBC_NAMESPACE::fputil::internal::FPRep;
using Rep = FPRep<FPType::IEEE754_Binary16>;
using u16 = uint16_t;
- EXPECT_EQ(u16(0b0'00000'0000000000), Rep::zero());
- EXPECT_EQ(u16(0b0'01111'0000000000), Rep::one());
- EXPECT_EQ(u16(0b0'00000'0000000001), Rep::min_subnormal());
- EXPECT_EQ(u16(0b0'00000'1111111111), Rep::max_subnormal());
- EXPECT_EQ(u16(0b0'00001'0000000000), Rep::min_normal());
- EXPECT_EQ(u16(0b0'11110'1111111111), Rep::max_normal());
- EXPECT_EQ(u16(0b0'11111'0000000000), Rep::inf());
- EXPECT_EQ(u16(0b0'11111'0100000000), Rep::build_nan());
- EXPECT_EQ(u16(0b0'11111'1000000000), Rep::build_quiet_nan());
+ EXPECT_REP_EQ(u16(0b0'00000'0000000000), Rep::zero());
+ EXPECT_REP_EQ(u16(0b0'01111'0000000000), Rep::one());
+ EXPECT_REP_EQ(u16(0b0'00000'0000000001), Rep::min_subnormal());
+ EXPECT_REP_EQ(u16(0b0'00000'1111111111), Rep::max_subnormal());
+ EXPECT_REP_EQ(u16(0b0'00001'0000000000), Rep::min_normal());
+ EXPECT_REP_EQ(u16(0b0'11110'1111111111), Rep::max_normal());
+ EXPECT_REP_EQ(u16(0b0'11111'0000000000), Rep::inf());
+ EXPECT_REP_EQ(u16(0b0'11111'0100000000), Rep::build_nan());
+ EXPECT_REP_EQ(u16(0b0'11111'1000000000), Rep::build_quiet_nan());
}
TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary32) {
@@ -36,15 +38,18 @@ TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary32) {
using Rep = FPRep<FPType::IEEE754_Binary32>;
using u32 = uint32_t;
- EXPECT_EQ(u32(0b0'00000000'00000000000000000000000), Rep::zero());
- EXPECT_EQ(u32(0b0'01111111'00000000000000000000000), Rep::one());
- EXPECT_EQ(u32(0b0'00000000'00000000000000000000001), Rep::min_subnormal());
- EXPECT_EQ(u32(0b0'00000000'11111111111111111111111), Rep::max_subnormal());
- EXPECT_EQ(u32(0b0'00000001'00000000000000000000000), Rep::min_normal());
- EXPECT_EQ(u32(0b0'11111110'11111111111111111111111), Rep::max_normal());
- EXPECT_EQ(u32(0b0'11111111'00000000000000000000000), Rep::inf());
- EXPECT_EQ(u32(0b0'11111111'01000000000000000000000), Rep::build_nan());
- EXPECT_EQ(u32(0b0'11111111'10000000000000000000000), Rep::build_quiet_nan());
+ EXPECT_REP_EQ(u32(0b0'00000000'00000000000000000000000), Rep::zero());
+ EXPECT_REP_EQ(u32(0b0'01111111'00000000000000000000000), Rep::one());
+ EXPECT_REP_EQ(u32(0b0'00000000'00000000000000000000001),
+ Rep::min_subnormal());
+ EXPECT_REP_EQ(u32(0b0'00000000'11111111111111111111111),
+ Rep::max_subnormal());
+ EXPECT_REP_EQ(u32(0b0'00000001'00000000000000000000000), Rep::min_normal());
+ EXPECT_REP_EQ(u32(0b0'11111110'11111111111111111111111), Rep::max_normal());
+ EXPECT_REP_EQ(u32(0b0'11111111'00000000000000000000000), Rep::inf());
+ EXPECT_REP_EQ(u32(0b0'11111111'01000000000000000000000), Rep::build_nan());
+ EXPECT_REP_EQ(u32(0b0'11111111'10000000000000000000000),
+ Rep::build_quiet_nan());
}
TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary64) {
@@ -53,31 +58,31 @@ TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary64) {
using Rep = FPRep<FPType::IEEE754_Binary64>;
using u64 = uint64_t;
- EXPECT_EQ(
+ EXPECT_REP_EQ(
u64(0b0'00000000000'0000000000000000000000000000000000000000000000000000),
Rep::zero());
- EXPECT_EQ(
+ EXPECT_REP_EQ(
u64(0b0'01111111111'0000000000000000000000000000000000000000000000000000),
Rep::one());
- EXPECT_EQ(
+ EXPECT_REP_EQ(
u64(0b0'00000000000'0000000000000000000000000000000000000000000000000001),
Rep::min_subnormal());
- EXPECT_EQ(
+ EXPECT_REP_EQ(
u64(0b0'00000000000'1111111111111111111111111111111111111111111111111111),
Rep::max_subnormal());
- EXPECT_EQ(
+ EXPECT_REP_EQ(
u64(0b0'00000000001'0000000000000000000000000000000000000000000000000000),
Rep::min_normal());
- EXPECT_EQ(
+ EXPECT_REP_EQ(
u64(0b0'11111111110'1111111111111111111111111111111111111111111111111111),
Rep::max_normal());
- EXPECT_EQ(
+ EXPECT_REP_EQ(
u64(0b0'11111111111'0000000000000000000000000000000000000000000000000000),
Rep::inf());
- EXPECT_EQ(
+ EXPECT_REP_EQ(
u64(0b0'11111111111'0100000000000000000000000000000000000000000000000000),
Rep::build_nan());
- EXPECT_EQ(
+ EXPECT_REP_EQ(
u64(0b0'11111111111'1000000000000000000000000000000000000000000000000000),
Rep::build_quiet_nan());
}
@@ -90,44 +95,87 @@ static constexpr UInt128 u128(uint64_t hi, uint64_t lo) {
#endif
}
+TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary128) {
+ using LIBC_NAMESPACE::fputil::FPType;
+ using LIBC_NAMESPACE::fputil::internal::FPRep;
+ using Rep = FPRep<FPType::IEEE754_Binary128>;
+
+ EXPECT_REP_EQ(
+ u128(0b0'000000000000000'000000000000000000000000000000000000000000000000,
+ 0b0000000000000000000000000000000000000000000000000000000000000000),
+ Rep::zero());
+ EXPECT_REP_EQ(
+ u128(0b0'011111111111111'000000000000000000000000000000000000000000000000,
+ 0b0000000000000000000000000000000000000000000000000000000000000000),
+ Rep::one());
+ EXPECT_REP_EQ(
+ u128(0b0'000000000000000'000000000000000000000000000000000000000000000000,
+ 0b0000000000000000000000000000000000000000000000000000000000000001),
+ Rep::min_subnormal());
+ EXPECT_REP_EQ(
+ u128(0b0'000000000000000'111111111111111111111111111111111111111111111111,
+ 0b1111111111111111111111111111111111111111111111111111111111111111),
+ Rep::max_subnormal());
+ EXPECT_REP_EQ(
+ u128(0b0'000000000000001'000000000000000000000000000000000000000000000000,
+ 0b0000000000000000000000000000000000000000000000000000000000000000),
+ Rep::min_normal());
+ EXPECT_REP_EQ(
+ u128(0b0'111111111111110'111111111111111111111111111111111111111111111111,
+ 0b1111111111111111111111111111111111111111111111111111111111111111),
+ Rep::max_normal());
+ EXPECT_REP_EQ(
+ u128(0b0'111111111111111'000000000000000000000000000000000000000000000000,
+ 0b0000000000000000000000000000000000000000000000000000000000000000),
+ Rep::inf());
+ EXPECT_REP_EQ(
+ u128(0b0'111111111111111'010000000000000000000000000000000000000000000000,
+ 0b0000000000000000000000000000000000000000000000000000000000000000),
+ Rep::build_nan());
+ EXPECT_REP_EQ(
+ u128(0b0'111111111111111'100000000000000000000000000000000000000000000000,
+ 0b0000000000000000000000000000000000000000000000000000000000000000),
+ Rep::build_quiet_nan());
+}
+
TEST(LlvmLibcFPBitsTest, FPType_X86_Binary80) {
using LIBC_NAMESPACE::fputil::FPType;
using LIBC_NAMESPACE::fputil::internal::FPRep;
using Rep = FPRep<FPType::X86_Binary80>;
- EXPECT_EQ(
+ EXPECT_REP_EQ(
u128(0b0'000000000000000,
0b0000000000000000000000000000000000000000000000000000000000000000),
Rep::zero());
- EXPECT_EQ(
+ EXPECT_REP_EQ(
u128(0b0'011111111111111,
0b1000000000000000000000000000000000000000000000000000000000000000),
Rep::one());
- EXPECT_EQ(
+ EXPECT_REP_EQ(
u128(0b0'000000000000000,
0b0000000000000000000000000000000000000000000000000000000000000001),
Rep::min_subnormal());
- EXPECT_EQ(
+ EXPECT_REP_EQ(
u128(0b0'000000000000000,
0b0111111111111111111111111111111111111111111111111111111111111111),
Rep::max_subnormal());
- EXPECT_EQ(
+ EXPECT_REP_EQ(
u128(0b0'000000000000001,
0b1000000000000000000000000000000000000000000000000000000000000000),
Rep::min_normal());
- EXPECT_EQ(
+ EXPECT_REP_EQ(
u128(0b0'111111111111110,
0b1111111111111111111111111111111111111111111111111111111111111111),
Rep::max_normal());
- EXPECT_EQ(
+ EXPECT_REP_EQ(
u128(0b0'111111111111111,
0b1000000000000000000000000000000000000000000000000000000000000000),
Rep::inf());
- EXPECT_EQ(
+ EXPECT_REP_EQ(
u128(0b0'111111111111111,
0b1010000000000000000000000000000000000000000000000000000000000000),
Rep::build_nan());
- EXPECT_EQ(
+ EXPECT_REP_EQ(
u128(0b0'111111111111111,
0b1100000000000000000000000000000000000000000000000000000000000000),
Rep::build_quiet_nan());
@@ -183,49 +231,6 @@ TEST(LlvmLibcFPBitsTest, FPType_X86_Binary80_IsNan) {
0b1000000000000000000000000000000000000000000000000000000000000000));
}
-TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary128) {
- using LIBC_NAMESPACE::fputil::FPType;
- using LIBC_NAMESPACE::fputil::internal::FPRep;
- using Rep = FPRep<FPType::IEEE754_Binary128>;
-
- EXPECT_EQ(
- u128(0b0'000000000000000'000000000000000000000000000000000000000000000000,
- 0b0000000000000000000000000000000000000000000000000000000000000000),
- Rep::zero());
- EXPECT_EQ(
- u128(0b0'011111111111111'000000000000000000000000000000000000000000000000,
- 0b0000000000000000000000000000000000000000000000000000000000000000),
- Rep::one());
- EXPECT_EQ(
- u128(0b0'000000000000000'000000000000000000000000000000000000000000000000,
- 0b0000000000000000000000000000000000000000000000000000000000000001),
- Rep::min_subnormal());
- EXPECT_EQ(
- u128(0b0'000000000000000'111111111111111111111111111111111111111111111111,
- 0b1111111111111111111111111111111111111111111111111111111111111111),
- Rep::max_subnormal());
- EXPECT_EQ(
- u128(0b0'000000000000001'000000000000000000000000000000000000000000000000,
- 0b0000000000000000000000000000000000000000000000000000000000000000),
- Rep::min_normal());
- EXPECT_EQ(
- u128(0b0'111111111111110'111111111111111111111111111111111111111111111111,
- 0b1111111111111111111111111111111111111111111111111111111111111111),
- Rep::max_normal());
- EXPECT_EQ(
- u128(0b0'111111111111111'000000000000000000000000000000000000000000000000,
- 0b0000000000000000000000000000000000000000000000000000000000000000),
- Rep::inf());
- EXPECT_EQ(
- u128(0b0'111111111111111'010000000000000000000000000000000000000000000000,
- 0b0000000000000000000000000000000000000000000000000000000000000000),
- Rep::build_nan());
- EXPECT_EQ(
- u128(0b0'111111111111111'100000000000000000000000000000000000000000000000,
- 0b0000000000000000000000000000000000000000000000000000000000000000),
- Rep::build_quiet_nan());
-}
-
TEST(LlvmLibcFPBitsTest, FloatType) {
using FloatBits = FPBits<float>;
More information about the libc-commits
mailing list