Skip to content

Commit 6b21e17

Browse files
authored
[libc] Add WordTypeSelector<16> specialization (#94979)
1 parent 88ff246 commit 6b21e17

File tree

6 files changed

+25
-6
lines changed

6 files changed

+25
-6
lines changed

libc/src/__support/FPUtil/CMakeLists.txt

-1
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,6 @@ add_header_library(
217217
.nearest_integer_operations
218218
.normal_float
219219
libc.hdr.math_macros
220-
libc.src.__support.CPP.algorithm
221220
libc.src.__support.CPP.bit
222221
libc.src.__support.CPP.limits
223222
libc.src.__support.CPP.type_traits

libc/src/__support/FPUtil/ManipulationFunctions.h

+2-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
#include "rounding_mode.h"
1717

1818
#include "hdr/math_macros.h"
19-
#include "src/__support/CPP/algorithm.h"
2019
#include "src/__support/CPP/bit.h"
2120
#include "src/__support/CPP/limits.h" // INT_MAX, INT_MIN
2221
#include "src/__support/CPP/type_traits.h"
@@ -103,7 +102,7 @@ intlogb(U x) {
103102
return IntLogbConstants<T>::T_MAX;
104103
}
105104

106-
DyadicFloat<cpp::max(FPBits<U>::STORAGE_LEN, 32)> normal(bits.get_val());
105+
DyadicFloat<FPBits<U>::STORAGE_LEN> normal(bits.get_val());
107106
int exponent = normal.get_unbiased_exponent();
108107
// The C standard does not specify the return value when an exponent is
109108
// out of int range. However, XSI conformance required that INT_MAX or
@@ -139,7 +138,7 @@ LIBC_INLINE constexpr T logb(T x) {
139138
return FPBits<T>::inf().get_val();
140139
}
141140

142-
DyadicFloat<cpp::max(FPBits<T>::STORAGE_LEN, 32)> normal(bits.get_val());
141+
DyadicFloat<FPBits<T>::STORAGE_LEN> normal(bits.get_val());
143142
return static_cast<T>(normal.get_unbiased_exponent());
144143
}
145144

libc/src/__support/big_int.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,8 @@ LIBC_INLINE constexpr cpp::array<word, N> shift(cpp::array<word, N> array,
299299
if (bit_offset == 0)
300300
dst = part1; // no crosstalk between parts.
301301
else if constexpr (direction == LEFT)
302-
dst = (part1 << bit_offset) | (part2 >> (WORD_BITS - bit_offset));
302+
dst = static_cast<word>((part1 << bit_offset) |
303+
(part2 >> (WORD_BITS - bit_offset)));
303304
else
304305
dst = (part1 >> bit_offset) | (part2 << (WORD_BITS - bit_offset));
305306
}
@@ -969,7 +970,8 @@ struct WordTypeSelector : cpp::type_identity<
969970
#endif // LIBC_TYPES_HAS_INT64
970971
> {
971972
};
972-
// Except if we request 32 bits explicitly.
973+
// Except if we request 16 or 32 bits explicitly.
974+
template <> struct WordTypeSelector<16> : cpp::type_identity<uint16_t> {};
973975
template <> struct WordTypeSelector<32> : cpp::type_identity<uint32_t> {};
974976
template <size_t Bits>
975977
using WordTypeSelectorT = typename WordTypeSelector<Bits>::type;

libc/test/src/__support/FPUtil/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ add_fp_unittest(
99
dyadic_float_test.cpp
1010
DEPENDS
1111
libc.src.__support.FPUtil.dyadic_float
12+
libc.src.__support.macros.properties.types
1213
COMPILE_OPTIONS
1314
# Prevent constant folding with a default rounding mode.
1415
"-frounding-math"

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

+4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "src/__support/FPUtil/dyadic_float.h"
1010
#include "src/__support/big_int.h"
11+
#include "src/__support/macros/properties/types.h"
1112
#include "test/UnitTest/FPMatcher.h"
1213
#include "test/UnitTest/Test.h"
1314
#include "utils/MPFRWrapper/MPFRUtils.h"
@@ -89,3 +90,6 @@ TEST(LlvmLibcDyadicFloatTest, QuickMul) {
8990
TEST_EDGE_RANGES(Float, float);
9091
TEST_EDGE_RANGES(Double, double);
9192
TEST_EDGE_RANGES(LongDouble, long double);
93+
#ifdef LIBC_TYPES_HAS_FLOAT16
94+
TEST_EDGE_RANGES(Float16, float16);
95+
#endif

libc/test/src/__support/big_int_test.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ TYPED_TEST(LlvmLibcUIntClassTest, CountBits, Types) {
205205
}
206206
}
207207

208+
using LL_UInt16 = UInt<16>;
208209
using LL_UInt64 = UInt<64>;
209210
// We want to test UInt<128> explicitly. So, for
210211
// convenience, we use a sugar which does not conflict with the UInt128 type
@@ -258,6 +259,19 @@ TEST(LlvmLibcUIntClassTest, BitCastToFromNativeFloat128) {
258259
}
259260
#endif // LIBC_TYPES_HAS_FLOAT128
260261

262+
#ifdef LIBC_TYPES_HAS_FLOAT16
263+
TEST(LlvmLibcUIntClassTest, BitCastToFromNativeFloat16) {
264+
static_assert(cpp::is_trivially_copyable<LL_UInt16>::value);
265+
static_assert(sizeof(LL_UInt16) == sizeof(float16));
266+
const float16 array[] = {0, 0.1, 1};
267+
for (float16 value : array) {
268+
LL_UInt16 back = cpp::bit_cast<LL_UInt16>(value);
269+
float16 forth = cpp::bit_cast<float16>(back);
270+
EXPECT_TRUE(value == forth);
271+
}
272+
}
273+
#endif // LIBC_TYPES_HAS_FLOAT16
274+
261275
TEST(LlvmLibcUIntClassTest, BasicInit) {
262276
LL_UInt128 half_val(12345);
263277
LL_UInt128 full_val({12345, 67890});

0 commit comments

Comments
 (0)