[libc-commits] [libc] [libc] Add WordTypeSelector<16> specialization (PR #94979)

via libc-commits libc-commits at lists.llvm.org
Mon Jun 10 06:42:47 PDT 2024


https://github.com/overmighty created https://github.com/llvm/llvm-project/pull/94979

None

>From 36b81e69e15c5bf5d95102f32c0acafc71c26389 Mon Sep 17 00:00:00 2001
From: OverMighty <its.overmighty at gmail.com>
Date: Mon, 10 Jun 2024 14:25:45 +0200
Subject: [PATCH 1/2] [libc] Add WordTypeSelector<16> specialization

---
 libc/src/__support/FPUtil/CMakeLists.txt          | 1 -
 libc/src/__support/FPUtil/ManipulationFunctions.h | 5 ++---
 libc/src/__support/big_int.h                      | 6 ++++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt
index 1744f8cf626f3..01ca4254c7996 100644
--- a/libc/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/src/__support/FPUtil/CMakeLists.txt
@@ -217,7 +217,6 @@ add_header_library(
     .nearest_integer_operations
     .normal_float
     libc.hdr.math_macros
-    libc.src.__support.CPP.algorithm
     libc.src.__support.CPP.bit
     libc.src.__support.CPP.limits
     libc.src.__support.CPP.type_traits
diff --git a/libc/src/__support/FPUtil/ManipulationFunctions.h b/libc/src/__support/FPUtil/ManipulationFunctions.h
index f695b83fb0b0b..a289c2ef70467 100644
--- a/libc/src/__support/FPUtil/ManipulationFunctions.h
+++ b/libc/src/__support/FPUtil/ManipulationFunctions.h
@@ -16,7 +16,6 @@
 #include "rounding_mode.h"
 
 #include "hdr/math_macros.h"
-#include "src/__support/CPP/algorithm.h"
 #include "src/__support/CPP/bit.h"
 #include "src/__support/CPP/limits.h" // INT_MAX, INT_MIN
 #include "src/__support/CPP/type_traits.h"
@@ -103,7 +102,7 @@ intlogb(U x) {
     return IntLogbConstants<T>::T_MAX;
   }
 
-  DyadicFloat<cpp::max(FPBits<U>::STORAGE_LEN, 32)> normal(bits.get_val());
+  DyadicFloat<FPBits<U>::STORAGE_LEN> normal(bits.get_val());
   int exponent = normal.get_unbiased_exponent();
   // The C standard does not specify the return value when an exponent is
   // out of int range. However, XSI conformance required that INT_MAX or
@@ -139,7 +138,7 @@ LIBC_INLINE constexpr T logb(T x) {
     return FPBits<T>::inf().get_val();
   }
 
-  DyadicFloat<cpp::max(FPBits<T>::STORAGE_LEN, 32)> normal(bits.get_val());
+  DyadicFloat<FPBits<T>::STORAGE_LEN> normal(bits.get_val());
   return static_cast<T>(normal.get_unbiased_exponent());
 }
 
diff --git a/libc/src/__support/big_int.h b/libc/src/__support/big_int.h
index e2061c4300702..40ad6eeed7ac2 100644
--- a/libc/src/__support/big_int.h
+++ b/libc/src/__support/big_int.h
@@ -299,7 +299,8 @@ LIBC_INLINE constexpr cpp::array<word, N> shift(cpp::array<word, N> array,
     if (bit_offset == 0)
       dst = part1; // no crosstalk between parts.
     else if constexpr (direction == LEFT)
-      dst = (part1 << bit_offset) | (part2 >> (WORD_BITS - bit_offset));
+      dst = static_cast<word>((part1 << bit_offset) |
+                              (part2 >> (WORD_BITS - bit_offset)));
     else
       dst = (part1 >> bit_offset) | (part2 << (WORD_BITS - bit_offset));
   }
@@ -969,7 +970,8 @@ struct WordTypeSelector : cpp::type_identity<
 #endif // LIBC_TYPES_HAS_INT64
                               > {
 };
-// Except if we request 32 bits explicitly.
+// Except if we request 16 or 32 bits explicitly.
+template <> struct WordTypeSelector<16> : cpp::type_identity<uint16_t> {};
 template <> struct WordTypeSelector<32> : cpp::type_identity<uint32_t> {};
 template <size_t Bits>
 using WordTypeSelectorT = typename WordTypeSelector<Bits>::type;

>From 60f20b108d35963e69b0f01460582ae7a468c353 Mon Sep 17 00:00:00 2001
From: OverMighty <its.overmighty at gmail.com>
Date: Mon, 10 Jun 2024 15:40:46 +0200
Subject: [PATCH 2/2] [libc] Add tests for UInt<16> and DyadicFloat<16>

---
 libc/test/src/__support/FPUtil/CMakeLists.txt      |  1 +
 .../src/__support/FPUtil/dyadic_float_test.cpp     |  4 ++++
 libc/test/src/__support/big_int_test.cpp           | 14 ++++++++++++++
 3 files changed, 19 insertions(+)

diff --git a/libc/test/src/__support/FPUtil/CMakeLists.txt b/libc/test/src/__support/FPUtil/CMakeLists.txt
index 1cbeec0cc4eb0..22fbd2664b546 100644
--- a/libc/test/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/test/src/__support/FPUtil/CMakeLists.txt
@@ -9,6 +9,7 @@ add_fp_unittest(
     dyadic_float_test.cpp
   DEPENDS
     libc.src.__support.FPUtil.dyadic_float
+    libc.src.__support.macros.properties.types
   COMPILE_OPTIONS
     # Prevent constant folding with a default rounding mode.
     "-frounding-math"
diff --git a/libc/test/src/__support/FPUtil/dyadic_float_test.cpp b/libc/test/src/__support/FPUtil/dyadic_float_test.cpp
index 809381ed47b59..3b1f9deb64ac8 100644
--- a/libc/test/src/__support/FPUtil/dyadic_float_test.cpp
+++ b/libc/test/src/__support/FPUtil/dyadic_float_test.cpp
@@ -8,6 +8,7 @@
 
 #include "src/__support/FPUtil/dyadic_float.h"
 #include "src/__support/big_int.h"
+#include "src/__support/macros/properties/types.h"
 #include "test/UnitTest/FPMatcher.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
@@ -89,3 +90,6 @@ TEST(LlvmLibcDyadicFloatTest, QuickMul) {
 TEST_EDGE_RANGES(Float, float);
 TEST_EDGE_RANGES(Double, double);
 TEST_EDGE_RANGES(LongDouble, long double);
+#ifdef LIBC_TYPES_HAS_FLOAT16
+TEST_EDGE_RANGES(Float16, float16);
+#endif
diff --git a/libc/test/src/__support/big_int_test.cpp b/libc/test/src/__support/big_int_test.cpp
index 1c4f0ac29171f..84cd206b3273c 100644
--- a/libc/test/src/__support/big_int_test.cpp
+++ b/libc/test/src/__support/big_int_test.cpp
@@ -205,6 +205,7 @@ TYPED_TEST(LlvmLibcUIntClassTest, CountBits, Types) {
   }
 }
 
+using LL_UInt16 = UInt<16>;
 using LL_UInt64 = UInt<64>;
 // We want to test UInt<128> explicitly. So, for
 // convenience, we use a sugar which does not conflict with the UInt128 type
@@ -258,6 +259,19 @@ TEST(LlvmLibcUIntClassTest, BitCastToFromNativeFloat128) {
 }
 #endif // LIBC_TYPES_HAS_FLOAT128
 
+#ifdef LIBC_TYPES_HAS_FLOAT16
+TEST(LlvmLibcUIntClassTest, BitCastToFromNativeFloat16) {
+  static_assert(cpp::is_trivially_copyable<LL_UInt16>::value);
+  static_assert(sizeof(LL_UInt16) == sizeof(float16));
+  const float16 array[] = {0, 0.1, 1};
+  for (float16 value : array) {
+    LL_UInt16 back = cpp::bit_cast<LL_UInt16>(value);
+    float16 forth = cpp::bit_cast<float16>(back);
+    EXPECT_TRUE(value == forth);
+  }
+}
+#endif // LIBC_TYPES_HAS_FLOAT16
+
 TEST(LlvmLibcUIntClassTest, BasicInit) {
   LL_UInt128 half_val(12345);
   LL_UInt128 full_val({12345, 67890});



More information about the libc-commits mailing list