Skip to content

Commit fd3edd4

Browse files
authored
[libc] Add test to check all properties for all FPBit types. (llvm#79851)
This test is platform agnostic, it runs all tests on all architectures.
1 parent 547113f commit fd3edd4

File tree

2 files changed

+91
-12
lines changed

2 files changed

+91
-12
lines changed

libc/src/__support/FPUtil/FPBits.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,9 @@ struct FPRep : public FPRepSem<fp_type, RetT> {
556556
using UP::FRACTION_MASK;
557557
using UP::SIGN_MASK;
558558

559+
LIBC_INLINE constexpr FPRep() = default;
560+
LIBC_INLINE constexpr explicit FPRep(StorageType x) : UP(x) {}
561+
559562
// Comparison
560563
LIBC_INLINE constexpr friend bool operator==(FPRep a, FPRep b) {
561564
return a.uintval() == b.uintval();

libc/test/src/__support/FPUtil/fpbits_test.cpp

Lines changed: 88 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@
1111
#include "test/UnitTest/Test.h"
1212

1313
using LIBC_NAMESPACE::fputil::FPBits;
14+
using LIBC_NAMESPACE::fputil::FPType;
1415
using LIBC_NAMESPACE::fputil::Sign;
16+
using LIBC_NAMESPACE::fputil::internal::FPRep;
1517

1618
TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary16) {
17-
using LIBC_NAMESPACE::fputil::FPType;
18-
using LIBC_NAMESPACE::fputil::internal::FPRep;
1919
using Rep = FPRep<FPType::IEEE754_Binary16>;
2020
using u16 = typename Rep::StorageType;
2121

@@ -31,8 +31,6 @@ TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary16) {
3131
}
3232

3333
TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary32) {
34-
using LIBC_NAMESPACE::fputil::FPType;
35-
using LIBC_NAMESPACE::fputil::internal::FPRep;
3634
using Rep = FPRep<FPType::IEEE754_Binary32>;
3735
using u32 = typename Rep::StorageType;
3836

@@ -51,8 +49,6 @@ TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary32) {
5149
}
5250

5351
TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary64) {
54-
using LIBC_NAMESPACE::fputil::FPType;
55-
using LIBC_NAMESPACE::fputil::internal::FPRep;
5652
using Rep = FPRep<FPType::IEEE754_Binary64>;
5753
using u64 = typename Rep::StorageType;
5854

@@ -94,8 +90,6 @@ static constexpr UInt128 u128(uint64_t hi, uint64_t lo) {
9490
}
9591

9692
TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary128) {
97-
using LIBC_NAMESPACE::fputil::FPType;
98-
using LIBC_NAMESPACE::fputil::internal::FPRep;
9993
using Rep = FPRep<FPType::IEEE754_Binary128>;
10094

10195
EXPECT_EQ(
@@ -137,8 +131,6 @@ TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary128) {
137131
}
138132

139133
TEST(LlvmLibcFPBitsTest, FPType_X86_Binary80) {
140-
using LIBC_NAMESPACE::fputil::FPType;
141-
using LIBC_NAMESPACE::fputil::internal::FPRep;
142134
using Rep = FPRep<FPType::X86_Binary80>;
143135

144136
EXPECT_EQ(
@@ -180,8 +172,6 @@ TEST(LlvmLibcFPBitsTest, FPType_X86_Binary80) {
180172
}
181173

182174
TEST(LlvmLibcFPBitsTest, FPType_X86_Binary80_IsNan) {
183-
using LIBC_NAMESPACE::fputil::FPType;
184-
using LIBC_NAMESPACE::fputil::internal::FPRep;
185175
using Rep = FPRep<FPType::X86_Binary80>;
186176

187177
const auto is_nan = [](uint64_t hi, uint64_t lo) {
@@ -229,6 +219,92 @@ TEST(LlvmLibcFPBitsTest, FPType_X86_Binary80_IsNan) {
229219
0b1000000000000000000000000000000000000000000000000000000000000000));
230220
}
231221

222+
enum class FP {
223+
ZERO,
224+
MIN_SUBNORMAL,
225+
MAX_SUBNORMAL,
226+
MIN_NORMAL,
227+
ONE,
228+
MAX_NORMAL,
229+
INF,
230+
BUILD_NAN,
231+
BUILD_QUIET_NAN
232+
};
233+
234+
using FPTypes = LIBC_NAMESPACE::testing::TypeList<
235+
FPRep<FPType::IEEE754_Binary16>, FPRep<FPType::IEEE754_Binary32>,
236+
FPRep<FPType::IEEE754_Binary64>, FPRep<FPType::IEEE754_Binary128>,
237+
FPRep<FPType::X86_Binary80>>;
238+
239+
// Tests all properties for all types of float.
240+
TYPED_TEST(LlvmLibcFPBitsTest, Properties, FPTypes) {
241+
static constexpr auto make_storage = [](Sign sign, FP fp) {
242+
switch (fp) {
243+
case FP::ZERO:
244+
return T::zero(sign);
245+
case FP::MIN_SUBNORMAL:
246+
return T::min_subnormal(sign);
247+
case FP::MAX_SUBNORMAL:
248+
return T::max_subnormal(sign);
249+
case FP::MIN_NORMAL:
250+
return T::min_normal(sign);
251+
case FP::ONE:
252+
return T::one(sign);
253+
case FP::MAX_NORMAL:
254+
return T::max_normal(sign);
255+
case FP::INF:
256+
return T::inf(sign);
257+
case FP::BUILD_NAN:
258+
return T::build_nan(sign);
259+
case FP::BUILD_QUIET_NAN:
260+
return T::build_quiet_nan(sign);
261+
}
262+
};
263+
static constexpr auto make = [](Sign sign, FP fp) -> T {
264+
return T(make_storage(sign, fp));
265+
};
266+
constexpr FP fp_values[] = {
267+
FP::ZERO, FP::MIN_SUBNORMAL, FP::MAX_SUBNORMAL,
268+
FP::MIN_NORMAL, FP::ONE, FP::MAX_NORMAL,
269+
FP::INF, FP::BUILD_NAN, FP::BUILD_QUIET_NAN};
270+
constexpr Sign signs[] = {Sign::POS, Sign::NEG};
271+
for (Sign sign : signs) {
272+
for (FP fp : fp_values) {
273+
const T value = make(sign, fp);
274+
// is_zero
275+
ASSERT_EQ(value.is_zero(), fp == FP::ZERO);
276+
// is_inf_or_nan
277+
ASSERT_EQ(value.is_inf_or_nan(), fp == FP::INF || fp == FP::BUILD_NAN ||
278+
fp == FP::BUILD_QUIET_NAN);
279+
// is_finite
280+
ASSERT_EQ(value.is_finite(), fp != FP::INF && fp != FP::BUILD_NAN &&
281+
fp != FP::BUILD_QUIET_NAN);
282+
// is_inf
283+
ASSERT_EQ(value.is_inf(), fp == FP::INF);
284+
// is_nan
285+
ASSERT_EQ(value.is_nan(),
286+
fp == FP::BUILD_NAN || fp == FP::BUILD_QUIET_NAN);
287+
// is_normal
288+
ASSERT_EQ(value.is_normal(),
289+
fp == FP::MIN_NORMAL || fp == FP::ONE || fp == FP::MAX_NORMAL);
290+
// is_quiet_nan
291+
ASSERT_EQ(value.is_quiet_nan(), fp == FP::BUILD_QUIET_NAN);
292+
// is_signaling_nan
293+
ASSERT_EQ(value.is_signaling_nan(), fp == FP::BUILD_NAN);
294+
// is_subnormal
295+
ASSERT_EQ(value.is_subnormal(), fp == FP::ZERO ||
296+
fp == FP::MIN_SUBNORMAL ||
297+
fp == FP::MAX_SUBNORMAL);
298+
// is_pos
299+
ASSERT_EQ(value.is_pos(), sign == Sign::POS);
300+
ASSERT_EQ(value.sign().is_pos(), sign == Sign::POS);
301+
// is_neg
302+
ASSERT_EQ(value.is_neg(), sign == Sign::NEG);
303+
ASSERT_EQ(value.sign().is_neg(), sign == Sign::NEG);
304+
}
305+
}
306+
}
307+
232308
TEST(LlvmLibcFPBitsTest, FloatType) {
233309
using FloatBits = FPBits<float>;
234310

0 commit comments

Comments
 (0)