Skip to content

[libc] Add WordTypeSelector<16> specialization #94979

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

Merged
merged 2 commits into from
Jun 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion libc/src/__support/FPUtil/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 2 additions & 3 deletions libc/src/__support/FPUtil/ManipulationFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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());
}

Expand Down
6 changes: 4 additions & 2 deletions libc/src/__support/big_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions libc/test/src/__support/FPUtil/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
4 changes: 4 additions & 0 deletions libc/test/src/__support/FPUtil/dyadic_float_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
14 changes: 14 additions & 0 deletions libc/test/src/__support/big_int_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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};
Copy link
Member Author

@overmighty overmighty Jun 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Literal suffixes weren't used in this file, so I omitted the f16 suffix here for consistency.

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});
Expand Down
Loading