Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[libc] Add test to check all properties for all FPBit types. #79851

Merged
merged 1 commit into from
Jan 30, 2024

Conversation

gchatelet
Copy link
Contributor

This test is platform agnostic, it runs all tests on all architectures.

This test is platform agnostic, it runs all tests on all architectures.
@llvmbot llvmbot added the libc label Jan 29, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Jan 29, 2024

@llvm/pr-subscribers-libc

Author: Guillaume Chatelet (gchatelet)

Changes

This test is platform agnostic, it runs all tests on all architectures.


Full diff: https://github.com/llvm/llvm-project/pull/79851.diff

2 Files Affected:

  • (modified) libc/src/__support/FPUtil/FPBits.h (+3)
  • (modified) libc/test/src/__support/FPUtil/fpbits_test.cpp (+88-12)
diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index e43c6168f1f47b..5277892ac3bb21 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -556,6 +556,9 @@ struct FPRep : public FPRepSem<fp_type, RetT> {
   using UP::FRACTION_MASK;
   using UP::SIGN_MASK;
 
+  LIBC_INLINE constexpr FPRep() = default;
+  LIBC_INLINE constexpr explicit FPRep(StorageType x) : UP(x) {}
+
   // Comparison
   LIBC_INLINE constexpr friend bool operator==(FPRep a, FPRep b) {
     return a.uintval() == b.uintval();
diff --git a/libc/test/src/__support/FPUtil/fpbits_test.cpp b/libc/test/src/__support/FPUtil/fpbits_test.cpp
index a4324a071536f8..990c4061427528 100644
--- a/libc/test/src/__support/FPUtil/fpbits_test.cpp
+++ b/libc/test/src/__support/FPUtil/fpbits_test.cpp
@@ -11,11 +11,11 @@
 #include "test/UnitTest/Test.h"
 
 using LIBC_NAMESPACE::fputil::FPBits;
+using LIBC_NAMESPACE::fputil::FPType;
 using LIBC_NAMESPACE::fputil::Sign;
+using LIBC_NAMESPACE::fputil::internal::FPRep;
 
 TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary16) {
-  using LIBC_NAMESPACE::fputil::FPType;
-  using LIBC_NAMESPACE::fputil::internal::FPRep;
   using Rep = FPRep<FPType::IEEE754_Binary16>;
   using u16 = typename Rep::StorageType;
 
@@ -31,8 +31,6 @@ TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary16) {
 }
 
 TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary32) {
-  using LIBC_NAMESPACE::fputil::FPType;
-  using LIBC_NAMESPACE::fputil::internal::FPRep;
   using Rep = FPRep<FPType::IEEE754_Binary32>;
   using u32 = typename Rep::StorageType;
 
@@ -51,8 +49,6 @@ TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary32) {
 }
 
 TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary64) {
-  using LIBC_NAMESPACE::fputil::FPType;
-  using LIBC_NAMESPACE::fputil::internal::FPRep;
   using Rep = FPRep<FPType::IEEE754_Binary64>;
   using u64 = typename Rep::StorageType;
 
@@ -94,8 +90,6 @@ static constexpr UInt128 u128(uint64_t hi, uint64_t lo) {
 }
 
 TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary128) {
-  using LIBC_NAMESPACE::fputil::FPType;
-  using LIBC_NAMESPACE::fputil::internal::FPRep;
   using Rep = FPRep<FPType::IEEE754_Binary128>;
 
   EXPECT_EQ(
@@ -137,8 +131,6 @@ TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary128) {
 }
 
 TEST(LlvmLibcFPBitsTest, FPType_X86_Binary80) {
-  using LIBC_NAMESPACE::fputil::FPType;
-  using LIBC_NAMESPACE::fputil::internal::FPRep;
   using Rep = FPRep<FPType::X86_Binary80>;
 
   EXPECT_EQ(
@@ -180,8 +172,6 @@ TEST(LlvmLibcFPBitsTest, FPType_X86_Binary80) {
 }
 
 TEST(LlvmLibcFPBitsTest, FPType_X86_Binary80_IsNan) {
-  using LIBC_NAMESPACE::fputil::FPType;
-  using LIBC_NAMESPACE::fputil::internal::FPRep;
   using Rep = FPRep<FPType::X86_Binary80>;
 
   const auto is_nan = [](uint64_t hi, uint64_t lo) {
@@ -229,6 +219,92 @@ TEST(LlvmLibcFPBitsTest, FPType_X86_Binary80_IsNan) {
       0b1000000000000000000000000000000000000000000000000000000000000000));
 }
 
+enum class FP {
+  ZERO,
+  MIN_SUBNORMAL,
+  MAX_SUBNORMAL,
+  MIN_NORMAL,
+  ONE,
+  MAX_NORMAL,
+  INF,
+  BUILD_NAN,
+  BUILD_QUIET_NAN
+};
+
+using FPTypes = LIBC_NAMESPACE::testing::TypeList<
+    FPRep<FPType::IEEE754_Binary16>, FPRep<FPType::IEEE754_Binary32>,
+    FPRep<FPType::IEEE754_Binary64>, FPRep<FPType::IEEE754_Binary128>,
+    FPRep<FPType::X86_Binary80>>;
+
+// Tests all properties for all types of float.
+TYPED_TEST(LlvmLibcFPBitsTest, Properties, FPTypes) {
+  static constexpr auto make_storage = [](Sign sign, FP fp) {
+    switch (fp) {
+    case FP::ZERO:
+      return T::zero(sign);
+    case FP::MIN_SUBNORMAL:
+      return T::min_subnormal(sign);
+    case FP::MAX_SUBNORMAL:
+      return T::max_subnormal(sign);
+    case FP::MIN_NORMAL:
+      return T::min_normal(sign);
+    case FP::ONE:
+      return T::one(sign);
+    case FP::MAX_NORMAL:
+      return T::max_normal(sign);
+    case FP::INF:
+      return T::inf(sign);
+    case FP::BUILD_NAN:
+      return T::build_nan(sign);
+    case FP::BUILD_QUIET_NAN:
+      return T::build_quiet_nan(sign);
+    }
+  };
+  static constexpr auto make = [](Sign sign, FP fp) -> T {
+    return T(make_storage(sign, fp));
+  };
+  constexpr FP fp_values[] = {
+      FP::ZERO,       FP::MIN_SUBNORMAL, FP::MAX_SUBNORMAL,
+      FP::MIN_NORMAL, FP::ONE,           FP::MAX_NORMAL,
+      FP::INF,        FP::BUILD_NAN,     FP::BUILD_QUIET_NAN};
+  constexpr Sign signs[] = {Sign::POS, Sign::NEG};
+  for (Sign sign : signs) {
+    for (FP fp : fp_values) {
+      const T value = make(sign, fp);
+      // is_zero
+      ASSERT_EQ(value.is_zero(), fp == FP::ZERO);
+      // is_inf_or_nan
+      ASSERT_EQ(value.is_inf_or_nan(), fp == FP::INF || fp == FP::BUILD_NAN ||
+                                           fp == FP::BUILD_QUIET_NAN);
+      // is_finite
+      ASSERT_EQ(value.is_finite(), fp != FP::INF && fp != FP::BUILD_NAN &&
+                                       fp != FP::BUILD_QUIET_NAN);
+      // is_inf
+      ASSERT_EQ(value.is_inf(), fp == FP::INF);
+      // is_nan
+      ASSERT_EQ(value.is_nan(),
+                fp == FP::BUILD_NAN || fp == FP::BUILD_QUIET_NAN);
+      // is_normal
+      ASSERT_EQ(value.is_normal(),
+                fp == FP::MIN_NORMAL || fp == FP::ONE || fp == FP::MAX_NORMAL);
+      // is_quiet_nan
+      ASSERT_EQ(value.is_quiet_nan(), fp == FP::BUILD_QUIET_NAN);
+      // is_signaling_nan
+      ASSERT_EQ(value.is_signaling_nan(), fp == FP::BUILD_NAN);
+      // is_subnormal
+      ASSERT_EQ(value.is_subnormal(), fp == FP::ZERO ||
+                                          fp == FP::MIN_SUBNORMAL ||
+                                          fp == FP::MAX_SUBNORMAL);
+      // is_pos
+      ASSERT_EQ(value.is_pos(), sign == Sign::POS);
+      ASSERT_EQ(value.sign().is_pos(), sign == Sign::POS);
+      // is_neg
+      ASSERT_EQ(value.is_neg(), sign == Sign::NEG);
+      ASSERT_EQ(value.sign().is_neg(), sign == Sign::NEG);
+    }
+  }
+}
+
 TEST(LlvmLibcFPBitsTest, FloatType) {
   using FloatBits = FPBits<float>;
 

@gchatelet gchatelet requested a review from lntue January 29, 2024 15:56
@gchatelet gchatelet merged commit fd3edd4 into llvm:main Jan 30, 2024
5 checks passed
@gchatelet gchatelet deleted the test_all_fp_properties branch January 30, 2024 09:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants