[libc-commits] [libc] [libc] Make `ceilf128` use the emulated float128 type (PR #206450)
via libc-commits
libc-commits at lists.llvm.org
Mon Jun 29 03:46:47 PDT 2026
https://github.com/Sukumarsawant updated https://github.com/llvm/llvm-project/pull/206450
>From 1c07f07900f009398608b9d21ddd42aa26c2e304 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 28 Jun 2026 00:16:39 +0530
Subject: [PATCH 01/44] test for constexpr failures
---
libc/src/__support/big_int.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/src/__support/big_int.h b/libc/src/__support/big_int.h
index 0e5c038ec356e..c1cf5b43fd1f5 100644
--- a/libc/src/__support/big_int.h
+++ b/libc/src/__support/big_int.h
@@ -358,7 +358,7 @@ struct BigInt {
LIBC_INLINE_VAR static constexpr size_t WORD_COUNT = Bits / WORD_SIZE;
- cpp::array<WordType, WORD_COUNT> val{}; // zero initialized.
+ cpp::array<WordType, WORD_COUNT> val; // zero initialized.
LIBC_INLINE constexpr BigInt() = default;
>From 7aabfa421ef39741ef5a8edeab6b294b7c1ca397 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 28 Jun 2026 00:56:14 +0530
Subject: [PATCH 02/44] bigint changes
---
libc/src/__support/big_int.h | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/libc/src/__support/big_int.h b/libc/src/__support/big_int.h
index c1cf5b43fd1f5..c71dfacf51608 100644
--- a/libc/src/__support/big_int.h
+++ b/libc/src/__support/big_int.h
@@ -366,7 +366,8 @@ struct BigInt {
template <size_t OtherBits, bool OtherSigned, typename OtherWordType>
LIBC_INLINE constexpr BigInt(
- const BigInt<OtherBits, OtherSigned, OtherWordType> &other) {
+ const BigInt<OtherBits, OtherSigned, OtherWordType> &other)
+ : val{} {
using BigIntOther = BigInt<OtherBits, OtherSigned, OtherWordType>;
[[maybe_unused]] const bool should_sign_extend = Signed && other.is_neg();
@@ -491,7 +492,7 @@ struct BigInt {
LIBC_INLINE static constexpr BigInt one() { return BigInt(1); }
LIBC_INLINE static constexpr BigInt all_ones() { return ~zero(); }
LIBC_INLINE static constexpr BigInt min() {
- BigInt out;
+ BigInt out{};
if constexpr (SIGNED)
out.set_msb();
return out;
>From 266b0830202ad9c51621b8c6dd01c6021d43add8 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 28 Jun 2026 01:03:50 +0530
Subject: [PATCH 03/44] mroe changes in bigint
---
libc/src/__support/big_int.h | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/libc/src/__support/big_int.h b/libc/src/__support/big_int.h
index c71dfacf51608..019c932870f92 100644
--- a/libc/src/__support/big_int.h
+++ b/libc/src/__support/big_int.h
@@ -637,7 +637,7 @@ struct BigInt {
// 256 4 16 10 3
// 512 8 64 36 7
LIBC_INLINE constexpr BigInt quick_mul_hi(const BigInt &other) const {
- BigInt result;
+ BigInt result{};
multiword::quick_mul_hi(result.val, val, other.val);
return result;
}
@@ -850,7 +850,7 @@ struct BigInt {
#define DEFINE_BINOP(OP) \
LIBC_INLINE friend constexpr BigInt operator OP(const BigInt &lhs, \
const BigInt &rhs) { \
- BigInt result; \
+ BigInt result{}; \
for (size_t i = 0; i < WORD_COUNT; ++i) \
result[i] = lhs[i] OP rhs[i]; \
return result; \
@@ -868,7 +868,7 @@ struct BigInt {
#undef DEFINE_BINOP
LIBC_INLINE constexpr BigInt operator~() const {
- BigInt result;
+ BigInt result{};
for (size_t i = 0; i < WORD_COUNT; ++i)
result[i] = static_cast<WordType>(~val[i]);
return result;
@@ -1315,7 +1315,7 @@ mask_trailing_ones() {
return T::all_ones();
constexpr size_t QUOTIENT = count / T::WORD_SIZE;
constexpr size_t REMAINDER = count % T::WORD_SIZE;
- T out; // zero initialized
+ T out{}; // zero initialized
for (size_t i = 0; i <= QUOTIENT; ++i)
out[i] = i < QUOTIENT
? cpp::numeric_limits<typename T::word_type>::max()
@@ -1331,7 +1331,7 @@ LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, T> mask_leading_ones() {
return T::all_ones();
constexpr size_t QUOTIENT = (T::BITS - count - 1U) / T::WORD_SIZE;
constexpr size_t REMAINDER = count % T::WORD_SIZE;
- T out; // zero initialized
+ T out{}; // zero initialized
for (size_t i = QUOTIENT; i < T::WORD_COUNT; ++i)
out[i] = i > QUOTIENT
? cpp::numeric_limits<typename T::word_type>::max()
>From fa370ee32c4b03e1e6e07c329476231303968df5 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 28 Jun 2026 01:10:09 +0530
Subject: [PATCH 04/44] nits
---
libc/src/__support/big_int.h | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/libc/src/__support/big_int.h b/libc/src/__support/big_int.h
index 019c932870f92..23677bd06fd68 100644
--- a/libc/src/__support/big_int.h
+++ b/libc/src/__support/big_int.h
@@ -457,20 +457,22 @@ struct BigInt {
}
// Construct a BigInt from a C array.
- template <size_t N> LIBC_INLINE constexpr BigInt(const WordType (&nums)[N]) {
+ template <size_t N>
+ LIBC_INLINE constexpr BigInt(const WordType (&nums)[N]) : val{} {
static_assert(N == WORD_COUNT);
for (size_t i = 0; i < WORD_COUNT; ++i)
val[i] = nums[i];
}
LIBC_INLINE constexpr explicit BigInt(
- const cpp::array<WordType, WORD_COUNT> &words) {
+ const cpp::array<WordType, WORD_COUNT> &words)
+ : val{} {
val = words;
}
// Initialize the first word to |v| and the rest to 0.
template <typename T, typename = cpp::enable_if_t<cpp::is_integral_v<T>>>
- LIBC_INLINE constexpr BigInt(T v) {
+ LIBC_INLINE constexpr BigInt(T v) : val{} {
constexpr size_t T_SIZE = sizeof(T) * CHAR_BIT;
const bool is_neg = v < 0;
for (size_t i = 0; i < WORD_COUNT; ++i) {
>From d4a92d25367033e13ec9e7d061e5f78f589523e2 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 28 Jun 2026 01:17:23 +0530
Subject: [PATCH 05/44] temp remove bit_cast (bigint - TC )
---
libc/src/__support/big_int.h | 50 ++++++++++++++++++------------------
1 file changed, 25 insertions(+), 25 deletions(-)
diff --git a/libc/src/__support/big_int.h b/libc/src/__support/big_int.h
index 23677bd06fd68..1d7de31da1d1d 100644
--- a/libc/src/__support/big_int.h
+++ b/libc/src/__support/big_int.h
@@ -1186,31 +1186,31 @@ LIBC_INLINE_VAR constexpr bool is_unsigned_integral_or_big_int_v =
is_unsigned_integral_or_big_int<T>::value;
namespace cpp {
-
-// Specialization of cpp::bit_cast ('bit.h') from T to BigInt.
-template <typename To, typename From>
-LIBC_INLINE LIBC_BIT_CAST_CONSTEXPR cpp::enable_if_t<
- (sizeof(To) == sizeof(From)) && cpp::is_trivially_copyable<To>::value &&
- cpp::is_trivially_copyable<From>::value && is_big_int<To>::value,
- To>
-bit_cast(const From &from) {
- To out;
- using Storage = decltype(out.val);
- out.val = cpp::bit_cast<Storage>(from);
- return out;
-}
-
-// Specialization of cpp::bit_cast ('bit.h') from BigInt to T.
-template <typename To, size_t Bits>
-LIBC_INLINE LIBC_BIT_CAST_CONSTEXPR
- cpp::enable_if_t<sizeof(To) == sizeof(UInt<Bits>) &&
- cpp::is_trivially_constructible<To>::value &&
- cpp::is_trivially_copyable<To>::value &&
- cpp::is_trivially_copyable<UInt<Bits>>::value,
- To>
- bit_cast(const UInt<Bits> &from) {
- return cpp::bit_cast<To>(from.val);
-}
+// Temporarily disabled
+// // Specialization of cpp::bit_cast ('bit.h') from T to BigInt.
+// template <typename To, typename From>
+// LIBC_INLINE LIBC_BIT_CAST_CONSTEXPR cpp::enable_if_t<
+// (sizeof(To) == sizeof(From)) && cpp::is_trivially_copyable<To>::value &&
+// cpp::is_trivially_copyable<From>::value && is_big_int<To>::value,
+// To>
+// bit_cast(const From &from) {
+// To out;
+// using Storage = decltype(out.val);
+// out.val = cpp::bit_cast<Storage>(from);
+// return out;
+// }
+
+// // Specialization of cpp::bit_cast ('bit.h') from BigInt to T.
+// template <typename To, size_t Bits>
+// LIBC_INLINE LIBC_BIT_CAST_CONSTEXPR
+// cpp::enable_if_t<sizeof(To) == sizeof(UInt<Bits>) &&
+// cpp::is_trivially_constructible<To>::value &&
+// cpp::is_trivially_copyable<To>::value &&
+// cpp::is_trivially_copyable<UInt<Bits>>::value,
+// To>
+// bit_cast(const UInt<Bits> &from) {
+// return cpp::bit_cast<To>(from.val);
+// }
// Specialization of cpp::popcount ('bit.h') for BigInt.
template <typename T>
>From 6f2683603b1da33fe4973e08057ec231a04a5a15 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 28 Jun 2026 01:27:09 +0530
Subject: [PATCH 06/44] integer_literals debug
---
.../src/__support/integer_literals_test.cpp | 310 +++++++++---------
1 file changed, 155 insertions(+), 155 deletions(-)
diff --git a/libc/test/src/__support/integer_literals_test.cpp b/libc/test/src/__support/integer_literals_test.cpp
index 5c626f43beb95..3e7ea59d86cda 100644
--- a/libc/test/src/__support/integer_literals_test.cpp
+++ b/libc/test/src/__support/integer_literals_test.cpp
@@ -1,155 +1,155 @@
-//===-- Unittests for user defined integer literals -----------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "src/__support/integer_literals.h"
-#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128
-#include "test/UnitTest/Test.h"
-
-using LIBC_NAMESPACE::operator""_u8;
-using LIBC_NAMESPACE::operator""_u16;
-using LIBC_NAMESPACE::operator""_u32;
-using LIBC_NAMESPACE::operator""_u64;
-using LIBC_NAMESPACE::operator""_u128;
-using LIBC_NAMESPACE::operator""_u256;
-
-TEST(LlvmLibcIntegerLiteralTest, u8) {
- EXPECT_EQ(uint8_t(0), 0_u8);
- EXPECT_EQ(uint8_t(UINT8_MAX), 255_u8);
- EXPECT_EQ(uint8_t(UINT8_MAX), 0xFF_u8);
- EXPECT_EQ(uint8_t(UINT8_MAX), 0b11111111_u8);
-}
-
-TEST(LlvmLibcIntegerLiteralTest, u16) {
- EXPECT_EQ(uint16_t(0), 0_u16);
- EXPECT_EQ(uint16_t(UINT8_MAX), 255_u16);
- EXPECT_EQ(uint16_t(UINT8_MAX), 0xFF_u16);
- EXPECT_EQ(uint16_t(UINT8_MAX), 0b11111111_u16);
- EXPECT_EQ(uint16_t(UINT16_MAX), 65535_u16);
- EXPECT_EQ(uint16_t(UINT16_MAX), 0xFFFF_u16);
- EXPECT_EQ(uint16_t(UINT16_MAX), 0b11111111'11111111_u16);
-}
-
-TEST(LlvmLibcIntegerLiteralTest, u32) {
- EXPECT_EQ(uint32_t(0), 0_u32);
- EXPECT_EQ(uint32_t(UINT8_MAX), 255_u32);
- EXPECT_EQ(uint32_t(UINT8_MAX), 0xFF_u32);
- EXPECT_EQ(uint32_t(UINT8_MAX), 0b11111111_u32);
- EXPECT_EQ(uint32_t(UINT16_MAX), 65535_u32);
- EXPECT_EQ(uint32_t(UINT16_MAX), 0xFFFF_u32);
- EXPECT_EQ(uint32_t(UINT16_MAX), 0b11111111'11111111_u32);
- EXPECT_EQ(uint32_t(UINT32_MAX), 4294967295_u32);
- EXPECT_EQ(uint32_t(UINT32_MAX), 0xFFFFFFFF_u32);
- EXPECT_EQ(uint32_t(UINT32_MAX), 0b1111111111111111'1111111111111111_u32);
-}
-
-TEST(LlvmLibcIntegerLiteralTest, u64) {
- EXPECT_EQ(uint64_t(0), 0_u64);
- EXPECT_EQ(uint64_t(UINT8_MAX), 255_u64);
- EXPECT_EQ(uint64_t(UINT8_MAX), 0xFF_u64);
- EXPECT_EQ(uint64_t(UINT8_MAX), 0b11111111_u64);
- EXPECT_EQ(uint64_t(UINT16_MAX), 65535_u64);
- EXPECT_EQ(uint64_t(UINT16_MAX), 0xFFFF_u64);
- EXPECT_EQ(uint64_t(UINT16_MAX), 0b11111111'11111111_u64);
- EXPECT_EQ(uint64_t(UINT32_MAX), 4294967295_u64);
- EXPECT_EQ(uint64_t(UINT32_MAX), 0xFFFFFFFF_u64);
- EXPECT_EQ(uint64_t(UINT32_MAX), 0b1111111111111111'1111111111111111_u64);
- EXPECT_EQ(uint64_t(UINT64_MAX), 18446744073709551615_u64);
- EXPECT_EQ(uint64_t(UINT64_MAX), 0xFFFFFFFF'FFFFFFFF_u64);
- EXPECT_EQ(
- uint64_t(UINT64_MAX),
- 0b1111111111111111'1111111111111111'1111111111111111'1111111111111111_u64);
-}
-
-TEST(LlvmLibcIntegerLiteralTest, u128) {
-#ifdef LIBC_TYPES_HAS_INT128
- const __uint128_t ZERO = 0;
- const __uint128_t U8_MAX = UINT8_MAX;
- const __uint128_t U16_MAX = UINT16_MAX;
- const __uint128_t U32_MAX = UINT32_MAX;
- const __uint128_t U64_MAX = UINT64_MAX;
- const __uint128_t U128_MAX = (U64_MAX << 64) | U64_MAX;
-#else
- const UInt128 ZERO = 0;
- const UInt128 U8_MAX = UINT8_MAX;
- const UInt128 U16_MAX = UINT16_MAX;
- const UInt128 U32_MAX = UINT32_MAX;
- const UInt128 U64_MAX = UINT64_MAX;
- const UInt128 U128_MAX = (U64_MAX << 64) | U64_MAX;
-#endif // LIBC_TYPES_HAS_INT128
- EXPECT_EQ(ZERO, 0_u128);
- EXPECT_EQ(U8_MAX, 255_u128);
- EXPECT_EQ(U8_MAX, 0xFF_u128);
- EXPECT_EQ(U8_MAX, 0b11111111_u128);
- EXPECT_EQ(U16_MAX, 65535_u128);
- EXPECT_EQ(U16_MAX, 0xFFFF_u128);
- EXPECT_EQ(U16_MAX, 0b11111111'11111111_u128);
- EXPECT_EQ(U32_MAX, 4294967295_u128);
- EXPECT_EQ(U32_MAX, 0xFFFFFFFF_u128);
- EXPECT_EQ(U32_MAX, 0b1111111111111111'1111111111111111_u128);
- EXPECT_EQ(U64_MAX, 18446744073709551615_u128);
- EXPECT_EQ(U64_MAX, 0xFFFFFFFF'FFFFFFFF_u128);
- EXPECT_EQ(
- U64_MAX,
- 0b1111111111111111'1111111111111111'1111111111111111'1111111111111111_u128);
- EXPECT_EQ(U128_MAX, 340282366920938463463374607431768211455_u128);
- EXPECT_EQ(U128_MAX, 0xFFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF_u128);
- EXPECT_EQ(
- U128_MAX,
- 0b1111111111111111'1111111111111111'1111111111111111'1111111111111111'1111111111111111'1111111111111111'1111111111111111'1111111111111111_u128);
-}
-
-TEST(LlvmLibcIntegerLiteralTest, u256) {
- using UInt256 = LIBC_NAMESPACE::UInt<256>;
- const UInt256 ZERO = 0;
- const UInt256 U8_MAX = UINT8_MAX;
- const UInt256 U16_MAX = UINT16_MAX;
- const UInt256 U32_MAX = UINT32_MAX;
- const UInt256 U64_MAX = UINT64_MAX;
- const UInt256 U128_MAX = (U64_MAX << 64) | U64_MAX;
- const UInt256 U256_MAX = (U128_MAX << 128) | U128_MAX;
- EXPECT_EQ(ZERO, 0_u256);
- EXPECT_EQ(U8_MAX, 255_u256);
- EXPECT_EQ(U8_MAX, 0xFF_u256);
- EXPECT_EQ(U8_MAX, 0b11111111_u256);
- EXPECT_EQ(U16_MAX, 65535_u256);
- EXPECT_EQ(U16_MAX, 0xFFFF_u256);
- EXPECT_EQ(U16_MAX, 0b11111111'11111111_u256);
- EXPECT_EQ(U32_MAX, 4294967295_u256);
- EXPECT_EQ(U32_MAX, 0xFFFFFFFF_u256);
- EXPECT_EQ(U32_MAX, 0b1111111111111111'1111111111111111_u256);
- EXPECT_EQ(U64_MAX, 18446744073709551615_u256);
- EXPECT_EQ(U64_MAX, 0xFFFFFFFF'FFFFFFFF_u256);
- EXPECT_EQ(
- U64_MAX,
- 0b1111111111111111'1111111111111111'1111111111111111'1111111111111111_u256);
- EXPECT_EQ(U128_MAX, 0xFFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF_u256);
- EXPECT_EQ(
- U256_MAX,
- 0xFFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF_u256);
-}
-
-TEST(LlvmLibcIntegerLiteralTest, parse_bigint) {
- using T = LIBC_NAMESPACE::Int<128>;
- struct {
- const char *str;
- T expected;
- } constexpr TEST_CASES[] = {
- {"0", 0}, {"-1", -1}, {"+1", 1}, {"-0xFF", -255}, {"-0b11", -3},
- };
- for (auto tc : TEST_CASES) {
- T actual = LIBC_NAMESPACE::parse_bigint<T>(tc.str);
- EXPECT_EQ(actual, tc.expected);
- }
-}
-
-TEST(LlvmLibcIntegerLiteralTest, parse_bigint_invalid) {
- using T = LIBC_NAMESPACE::Int<128>;
- const T expected; // default construction
- EXPECT_EQ(LIBC_NAMESPACE::parse_bigint<T>(nullptr), expected);
- EXPECT_EQ(LIBC_NAMESPACE::parse_bigint<T>(""), expected);
-}
+//===-- Unittests for user defined integer literals -----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/integer_literals.h"
+#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128
+#include "test/UnitTest/Test.h"
+
+using LIBC_NAMESPACE::operator""_u8;
+using LIBC_NAMESPACE::operator""_u16;
+using LIBC_NAMESPACE::operator""_u32;
+using LIBC_NAMESPACE::operator""_u64;
+using LIBC_NAMESPACE::operator""_u128;
+using LIBC_NAMESPACE::operator""_u256;
+
+TEST(LlvmLibcIntegerLiteralTest, u8) {
+ EXPECT_EQ(uint8_t(0), 0_u8);
+ EXPECT_EQ(uint8_t(UINT8_MAX), 255_u8);
+ EXPECT_EQ(uint8_t(UINT8_MAX), 0xFF_u8);
+ EXPECT_EQ(uint8_t(UINT8_MAX), 0b11111111_u8);
+}
+
+TEST(LlvmLibcIntegerLiteralTest, u16) {
+ EXPECT_EQ(uint16_t(0), 0_u16);
+ EXPECT_EQ(uint16_t(UINT8_MAX), 255_u16);
+ EXPECT_EQ(uint16_t(UINT8_MAX), 0xFF_u16);
+ EXPECT_EQ(uint16_t(UINT8_MAX), 0b11111111_u16);
+ EXPECT_EQ(uint16_t(UINT16_MAX), 65535_u16);
+ EXPECT_EQ(uint16_t(UINT16_MAX), 0xFFFF_u16);
+ EXPECT_EQ(uint16_t(UINT16_MAX), 0b11111111'11111111_u16);
+}
+
+TEST(LlvmLibcIntegerLiteralTest, u32) {
+ EXPECT_EQ(uint32_t(0), 0_u32);
+ EXPECT_EQ(uint32_t(UINT8_MAX), 255_u32);
+ EXPECT_EQ(uint32_t(UINT8_MAX), 0xFF_u32);
+ EXPECT_EQ(uint32_t(UINT8_MAX), 0b11111111_u32);
+ EXPECT_EQ(uint32_t(UINT16_MAX), 65535_u32);
+ EXPECT_EQ(uint32_t(UINT16_MAX), 0xFFFF_u32);
+ EXPECT_EQ(uint32_t(UINT16_MAX), 0b11111111'11111111_u32);
+ EXPECT_EQ(uint32_t(UINT32_MAX), 4294967295_u32);
+ EXPECT_EQ(uint32_t(UINT32_MAX), 0xFFFFFFFF_u32);
+ EXPECT_EQ(uint32_t(UINT32_MAX), 0b1111111111111111'1111111111111111_u32);
+}
+
+TEST(LlvmLibcIntegerLiteralTest, u64) {
+ EXPECT_EQ(uint64_t(0), 0_u64);
+ EXPECT_EQ(uint64_t(UINT8_MAX), 255_u64);
+ EXPECT_EQ(uint64_t(UINT8_MAX), 0xFF_u64);
+ EXPECT_EQ(uint64_t(UINT8_MAX), 0b11111111_u64);
+ EXPECT_EQ(uint64_t(UINT16_MAX), 65535_u64);
+ EXPECT_EQ(uint64_t(UINT16_MAX), 0xFFFF_u64);
+ EXPECT_EQ(uint64_t(UINT16_MAX), 0b11111111'11111111_u64);
+ EXPECT_EQ(uint64_t(UINT32_MAX), 4294967295_u64);
+ EXPECT_EQ(uint64_t(UINT32_MAX), 0xFFFFFFFF_u64);
+ EXPECT_EQ(uint64_t(UINT32_MAX), 0b1111111111111111'1111111111111111_u64);
+ EXPECT_EQ(uint64_t(UINT64_MAX), 18446744073709551615_u64);
+ EXPECT_EQ(uint64_t(UINT64_MAX), 0xFFFFFFFF'FFFFFFFF_u64);
+ EXPECT_EQ(
+ uint64_t(UINT64_MAX),
+ 0b1111111111111111'1111111111111111'1111111111111111'1111111111111111_u64);
+}
+
+TEST(LlvmLibcIntegerLiteralTest, u128) {
+#ifdef LIBC_TYPES_HAS_INT128
+ const __uint128_t ZERO = 0;
+ const __uint128_t U8_MAX = UINT8_MAX;
+ const __uint128_t U16_MAX = UINT16_MAX;
+ const __uint128_t U32_MAX = UINT32_MAX;
+ const __uint128_t U64_MAX = UINT64_MAX;
+ const __uint128_t U128_MAX = (U64_MAX << 64) | U64_MAX;
+#else
+ const UInt128 ZERO = 0;
+ const UInt128 U8_MAX = UINT8_MAX;
+ const UInt128 U16_MAX = UINT16_MAX;
+ const UInt128 U32_MAX = UINT32_MAX;
+ const UInt128 U64_MAX = UINT64_MAX;
+ const UInt128 U128_MAX = (U64_MAX << 64) | U64_MAX;
+#endif // LIBC_TYPES_HAS_INT128
+ EXPECT_EQ(ZERO, 0_u128);
+ EXPECT_EQ(U8_MAX, 255_u128);
+ EXPECT_EQ(U8_MAX, 0xFF_u128);
+ EXPECT_EQ(U8_MAX, 0b11111111_u128);
+ EXPECT_EQ(U16_MAX, 65535_u128);
+ EXPECT_EQ(U16_MAX, 0xFFFF_u128);
+ EXPECT_EQ(U16_MAX, 0b11111111'11111111_u128);
+ EXPECT_EQ(U32_MAX, 4294967295_u128);
+ EXPECT_EQ(U32_MAX, 0xFFFFFFFF_u128);
+ EXPECT_EQ(U32_MAX, 0b1111111111111111'1111111111111111_u128);
+ EXPECT_EQ(U64_MAX, 18446744073709551615_u128);
+ EXPECT_EQ(U64_MAX, 0xFFFFFFFF'FFFFFFFF_u128);
+ EXPECT_EQ(
+ U64_MAX,
+ 0b1111111111111111'1111111111111111'1111111111111111'1111111111111111_u128);
+ EXPECT_EQ(U128_MAX, 340282366920938463463374607431768211455_u128);
+ EXPECT_EQ(U128_MAX, 0xFFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF_u128);
+ EXPECT_EQ(
+ U128_MAX,
+ 0b1111111111111111'1111111111111111'1111111111111111'1111111111111111'1111111111111111'1111111111111111'1111111111111111'1111111111111111_u128);
+}
+
+TEST(LlvmLibcIntegerLiteralTest, u256) {
+ using UInt256 = LIBC_NAMESPACE::UInt<256>;
+ const UInt256 ZERO = 0;
+ const UInt256 U8_MAX = UINT8_MAX;
+ const UInt256 U16_MAX = UINT16_MAX;
+ const UInt256 U32_MAX = UINT32_MAX;
+ const UInt256 U64_MAX = UINT64_MAX;
+ const UInt256 U128_MAX = (U64_MAX << 64) | U64_MAX;
+ const UInt256 U256_MAX = (U128_MAX << 128) | U128_MAX;
+ EXPECT_EQ(ZERO, 0_u256);
+ EXPECT_EQ(U8_MAX, 255_u256);
+ EXPECT_EQ(U8_MAX, 0xFF_u256);
+ EXPECT_EQ(U8_MAX, 0b11111111_u256);
+ EXPECT_EQ(U16_MAX, 65535_u256);
+ EXPECT_EQ(U16_MAX, 0xFFFF_u256);
+ EXPECT_EQ(U16_MAX, 0b11111111'11111111_u256);
+ EXPECT_EQ(U32_MAX, 4294967295_u256);
+ EXPECT_EQ(U32_MAX, 0xFFFFFFFF_u256);
+ EXPECT_EQ(U32_MAX, 0b1111111111111111'1111111111111111_u256);
+ EXPECT_EQ(U64_MAX, 18446744073709551615_u256);
+ EXPECT_EQ(U64_MAX, 0xFFFFFFFF'FFFFFFFF_u256);
+ EXPECT_EQ(
+ U64_MAX,
+ 0b1111111111111111'1111111111111111'1111111111111111'1111111111111111_u256);
+ EXPECT_EQ(U128_MAX, 0xFFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF_u256);
+ EXPECT_EQ(
+ U256_MAX,
+ 0xFFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF_u256);
+}
+
+TEST(LlvmLibcIntegerLiteralTest, parse_bigint) {
+ using T = LIBC_NAMESPACE::Int<128>;
+ struct {
+ const char *str;
+ T expected;
+ } constexpr TEST_CASES[] = {
+ {"0", 0}, {"-1", -1}, {"+1", 1}, {"-0xFF", -255}, {"-0b11", -3},
+ };
+ for (auto tc : TEST_CASES) {
+ T actual = LIBC_NAMESPACE::parse_bigint<T>(tc.str);
+ EXPECT_EQ(actual, tc.expected);
+ }
+}
+
+TEST(LlvmLibcIntegerLiteralTest, parse_bigint_invalid) {
+ using T = LIBC_NAMESPACE::Int<128>;
+ const T expected{}; // default construction
+ EXPECT_EQ(LIBC_NAMESPACE::parse_bigint<T>(nullptr), expected);
+ EXPECT_EQ(LIBC_NAMESPACE::parse_bigint<T>(""), expected);
+}
>From 4cc8f63bc88bdb49093f251fdd95f4f92716ca93 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 28 Jun 2026 01:40:37 +0530
Subject: [PATCH 07/44] debug big_int errs + init
---
libc/src/__support/big_int.h | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/libc/src/__support/big_int.h b/libc/src/__support/big_int.h
index 1d7de31da1d1d..98bab6a7127ac 100644
--- a/libc/src/__support/big_int.h
+++ b/libc/src/__support/big_int.h
@@ -339,8 +339,8 @@ struct BigInt {
"WordType must be unsigned integer.");
struct Division {
- BigInt quotient;
- BigInt remainder;
+ BigInt quotient{};
+ BigInt remainder{};
};
public:
@@ -692,7 +692,7 @@ struct BigInt {
// And finally we perform some extra alignment steps for the remaining bits.
LIBC_INLINE constexpr cpp::optional<BigInt>
div_uint_half_times_pow_2(multiword::half_width_t<WordType> x, size_t e) {
- BigInt remainder;
+ BigInt remainder{};
if (x == 0)
return cpp::nullopt;
if (e >= Bits) {
@@ -700,7 +700,7 @@ struct BigInt {
*this = BigInt<Bits, false, WordType>();
return remainder;
}
- BigInt quotient;
+ BigInt quotient{};
WordType x_word = static_cast<WordType>(x);
constexpr size_t LOG2_WORD_SIZE =
static_cast<size_t>(cpp::bit_width(WORD_SIZE) - 1);
@@ -1010,7 +1010,7 @@ struct BigInt {
LIBC_INLINE constexpr static Division divide_unsigned(const BigInt ÷nd,
const BigInt ÷r) {
BigInt remainder = dividend;
- BigInt quotient;
+ BigInt quotient{};
if (remainder >= divider) {
BigInt subtractor = divider;
int cur_bit = multiword::countl_zero(subtractor.val) -
@@ -1392,6 +1392,11 @@ first_trailing_one(T value) {
return value == 0 ? 0 : cpp::countr_zero(value) + 1;
}
+static_assert(LIBC_NAMESPACE::cpp::is_trivially_constructible<
+ LIBC_NAMESPACE::BigInt<128, false>>::value);
+static_assert(LIBC_NAMESPACE::cpp::is_trivially_copyable<
+ LIBC_NAMESPACE::BigInt<128, false>>::value);
+
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SRC___SUPPORT_BIG_INT_H
>From 34ffde1e25c507127de52e924d8f52a468986089 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 28 Jun 2026 01:43:12 +0530
Subject: [PATCH 08/44] crlf-> lf
---
.../src/__support/integer_literals_test.cpp | 310 +++++++++---------
1 file changed, 155 insertions(+), 155 deletions(-)
diff --git a/libc/test/src/__support/integer_literals_test.cpp b/libc/test/src/__support/integer_literals_test.cpp
index 3e7ea59d86cda..fe51cfb8e4f65 100644
--- a/libc/test/src/__support/integer_literals_test.cpp
+++ b/libc/test/src/__support/integer_literals_test.cpp
@@ -1,155 +1,155 @@
-//===-- Unittests for user defined integer literals -----------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "src/__support/integer_literals.h"
-#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128
-#include "test/UnitTest/Test.h"
-
-using LIBC_NAMESPACE::operator""_u8;
-using LIBC_NAMESPACE::operator""_u16;
-using LIBC_NAMESPACE::operator""_u32;
-using LIBC_NAMESPACE::operator""_u64;
-using LIBC_NAMESPACE::operator""_u128;
-using LIBC_NAMESPACE::operator""_u256;
-
-TEST(LlvmLibcIntegerLiteralTest, u8) {
- EXPECT_EQ(uint8_t(0), 0_u8);
- EXPECT_EQ(uint8_t(UINT8_MAX), 255_u8);
- EXPECT_EQ(uint8_t(UINT8_MAX), 0xFF_u8);
- EXPECT_EQ(uint8_t(UINT8_MAX), 0b11111111_u8);
-}
-
-TEST(LlvmLibcIntegerLiteralTest, u16) {
- EXPECT_EQ(uint16_t(0), 0_u16);
- EXPECT_EQ(uint16_t(UINT8_MAX), 255_u16);
- EXPECT_EQ(uint16_t(UINT8_MAX), 0xFF_u16);
- EXPECT_EQ(uint16_t(UINT8_MAX), 0b11111111_u16);
- EXPECT_EQ(uint16_t(UINT16_MAX), 65535_u16);
- EXPECT_EQ(uint16_t(UINT16_MAX), 0xFFFF_u16);
- EXPECT_EQ(uint16_t(UINT16_MAX), 0b11111111'11111111_u16);
-}
-
-TEST(LlvmLibcIntegerLiteralTest, u32) {
- EXPECT_EQ(uint32_t(0), 0_u32);
- EXPECT_EQ(uint32_t(UINT8_MAX), 255_u32);
- EXPECT_EQ(uint32_t(UINT8_MAX), 0xFF_u32);
- EXPECT_EQ(uint32_t(UINT8_MAX), 0b11111111_u32);
- EXPECT_EQ(uint32_t(UINT16_MAX), 65535_u32);
- EXPECT_EQ(uint32_t(UINT16_MAX), 0xFFFF_u32);
- EXPECT_EQ(uint32_t(UINT16_MAX), 0b11111111'11111111_u32);
- EXPECT_EQ(uint32_t(UINT32_MAX), 4294967295_u32);
- EXPECT_EQ(uint32_t(UINT32_MAX), 0xFFFFFFFF_u32);
- EXPECT_EQ(uint32_t(UINT32_MAX), 0b1111111111111111'1111111111111111_u32);
-}
-
-TEST(LlvmLibcIntegerLiteralTest, u64) {
- EXPECT_EQ(uint64_t(0), 0_u64);
- EXPECT_EQ(uint64_t(UINT8_MAX), 255_u64);
- EXPECT_EQ(uint64_t(UINT8_MAX), 0xFF_u64);
- EXPECT_EQ(uint64_t(UINT8_MAX), 0b11111111_u64);
- EXPECT_EQ(uint64_t(UINT16_MAX), 65535_u64);
- EXPECT_EQ(uint64_t(UINT16_MAX), 0xFFFF_u64);
- EXPECT_EQ(uint64_t(UINT16_MAX), 0b11111111'11111111_u64);
- EXPECT_EQ(uint64_t(UINT32_MAX), 4294967295_u64);
- EXPECT_EQ(uint64_t(UINT32_MAX), 0xFFFFFFFF_u64);
- EXPECT_EQ(uint64_t(UINT32_MAX), 0b1111111111111111'1111111111111111_u64);
- EXPECT_EQ(uint64_t(UINT64_MAX), 18446744073709551615_u64);
- EXPECT_EQ(uint64_t(UINT64_MAX), 0xFFFFFFFF'FFFFFFFF_u64);
- EXPECT_EQ(
- uint64_t(UINT64_MAX),
- 0b1111111111111111'1111111111111111'1111111111111111'1111111111111111_u64);
-}
-
-TEST(LlvmLibcIntegerLiteralTest, u128) {
-#ifdef LIBC_TYPES_HAS_INT128
- const __uint128_t ZERO = 0;
- const __uint128_t U8_MAX = UINT8_MAX;
- const __uint128_t U16_MAX = UINT16_MAX;
- const __uint128_t U32_MAX = UINT32_MAX;
- const __uint128_t U64_MAX = UINT64_MAX;
- const __uint128_t U128_MAX = (U64_MAX << 64) | U64_MAX;
-#else
- const UInt128 ZERO = 0;
- const UInt128 U8_MAX = UINT8_MAX;
- const UInt128 U16_MAX = UINT16_MAX;
- const UInt128 U32_MAX = UINT32_MAX;
- const UInt128 U64_MAX = UINT64_MAX;
- const UInt128 U128_MAX = (U64_MAX << 64) | U64_MAX;
-#endif // LIBC_TYPES_HAS_INT128
- EXPECT_EQ(ZERO, 0_u128);
- EXPECT_EQ(U8_MAX, 255_u128);
- EXPECT_EQ(U8_MAX, 0xFF_u128);
- EXPECT_EQ(U8_MAX, 0b11111111_u128);
- EXPECT_EQ(U16_MAX, 65535_u128);
- EXPECT_EQ(U16_MAX, 0xFFFF_u128);
- EXPECT_EQ(U16_MAX, 0b11111111'11111111_u128);
- EXPECT_EQ(U32_MAX, 4294967295_u128);
- EXPECT_EQ(U32_MAX, 0xFFFFFFFF_u128);
- EXPECT_EQ(U32_MAX, 0b1111111111111111'1111111111111111_u128);
- EXPECT_EQ(U64_MAX, 18446744073709551615_u128);
- EXPECT_EQ(U64_MAX, 0xFFFFFFFF'FFFFFFFF_u128);
- EXPECT_EQ(
- U64_MAX,
- 0b1111111111111111'1111111111111111'1111111111111111'1111111111111111_u128);
- EXPECT_EQ(U128_MAX, 340282366920938463463374607431768211455_u128);
- EXPECT_EQ(U128_MAX, 0xFFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF_u128);
- EXPECT_EQ(
- U128_MAX,
- 0b1111111111111111'1111111111111111'1111111111111111'1111111111111111'1111111111111111'1111111111111111'1111111111111111'1111111111111111_u128);
-}
-
-TEST(LlvmLibcIntegerLiteralTest, u256) {
- using UInt256 = LIBC_NAMESPACE::UInt<256>;
- const UInt256 ZERO = 0;
- const UInt256 U8_MAX = UINT8_MAX;
- const UInt256 U16_MAX = UINT16_MAX;
- const UInt256 U32_MAX = UINT32_MAX;
- const UInt256 U64_MAX = UINT64_MAX;
- const UInt256 U128_MAX = (U64_MAX << 64) | U64_MAX;
- const UInt256 U256_MAX = (U128_MAX << 128) | U128_MAX;
- EXPECT_EQ(ZERO, 0_u256);
- EXPECT_EQ(U8_MAX, 255_u256);
- EXPECT_EQ(U8_MAX, 0xFF_u256);
- EXPECT_EQ(U8_MAX, 0b11111111_u256);
- EXPECT_EQ(U16_MAX, 65535_u256);
- EXPECT_EQ(U16_MAX, 0xFFFF_u256);
- EXPECT_EQ(U16_MAX, 0b11111111'11111111_u256);
- EXPECT_EQ(U32_MAX, 4294967295_u256);
- EXPECT_EQ(U32_MAX, 0xFFFFFFFF_u256);
- EXPECT_EQ(U32_MAX, 0b1111111111111111'1111111111111111_u256);
- EXPECT_EQ(U64_MAX, 18446744073709551615_u256);
- EXPECT_EQ(U64_MAX, 0xFFFFFFFF'FFFFFFFF_u256);
- EXPECT_EQ(
- U64_MAX,
- 0b1111111111111111'1111111111111111'1111111111111111'1111111111111111_u256);
- EXPECT_EQ(U128_MAX, 0xFFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF_u256);
- EXPECT_EQ(
- U256_MAX,
- 0xFFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF_u256);
-}
-
-TEST(LlvmLibcIntegerLiteralTest, parse_bigint) {
- using T = LIBC_NAMESPACE::Int<128>;
- struct {
- const char *str;
- T expected;
- } constexpr TEST_CASES[] = {
- {"0", 0}, {"-1", -1}, {"+1", 1}, {"-0xFF", -255}, {"-0b11", -3},
- };
- for (auto tc : TEST_CASES) {
- T actual = LIBC_NAMESPACE::parse_bigint<T>(tc.str);
- EXPECT_EQ(actual, tc.expected);
- }
-}
-
-TEST(LlvmLibcIntegerLiteralTest, parse_bigint_invalid) {
- using T = LIBC_NAMESPACE::Int<128>;
- const T expected{}; // default construction
- EXPECT_EQ(LIBC_NAMESPACE::parse_bigint<T>(nullptr), expected);
- EXPECT_EQ(LIBC_NAMESPACE::parse_bigint<T>(""), expected);
-}
+//===-- Unittests for user defined integer literals -----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/integer_literals.h"
+#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128
+#include "test/UnitTest/Test.h"
+
+using LIBC_NAMESPACE::operator""_u8;
+using LIBC_NAMESPACE::operator""_u16;
+using LIBC_NAMESPACE::operator""_u32;
+using LIBC_NAMESPACE::operator""_u64;
+using LIBC_NAMESPACE::operator""_u128;
+using LIBC_NAMESPACE::operator""_u256;
+
+TEST(LlvmLibcIntegerLiteralTest, u8) {
+ EXPECT_EQ(uint8_t(0), 0_u8);
+ EXPECT_EQ(uint8_t(UINT8_MAX), 255_u8);
+ EXPECT_EQ(uint8_t(UINT8_MAX), 0xFF_u8);
+ EXPECT_EQ(uint8_t(UINT8_MAX), 0b11111111_u8);
+}
+
+TEST(LlvmLibcIntegerLiteralTest, u16) {
+ EXPECT_EQ(uint16_t(0), 0_u16);
+ EXPECT_EQ(uint16_t(UINT8_MAX), 255_u16);
+ EXPECT_EQ(uint16_t(UINT8_MAX), 0xFF_u16);
+ EXPECT_EQ(uint16_t(UINT8_MAX), 0b11111111_u16);
+ EXPECT_EQ(uint16_t(UINT16_MAX), 65535_u16);
+ EXPECT_EQ(uint16_t(UINT16_MAX), 0xFFFF_u16);
+ EXPECT_EQ(uint16_t(UINT16_MAX), 0b11111111'11111111_u16);
+}
+
+TEST(LlvmLibcIntegerLiteralTest, u32) {
+ EXPECT_EQ(uint32_t(0), 0_u32);
+ EXPECT_EQ(uint32_t(UINT8_MAX), 255_u32);
+ EXPECT_EQ(uint32_t(UINT8_MAX), 0xFF_u32);
+ EXPECT_EQ(uint32_t(UINT8_MAX), 0b11111111_u32);
+ EXPECT_EQ(uint32_t(UINT16_MAX), 65535_u32);
+ EXPECT_EQ(uint32_t(UINT16_MAX), 0xFFFF_u32);
+ EXPECT_EQ(uint32_t(UINT16_MAX), 0b11111111'11111111_u32);
+ EXPECT_EQ(uint32_t(UINT32_MAX), 4294967295_u32);
+ EXPECT_EQ(uint32_t(UINT32_MAX), 0xFFFFFFFF_u32);
+ EXPECT_EQ(uint32_t(UINT32_MAX), 0b1111111111111111'1111111111111111_u32);
+}
+
+TEST(LlvmLibcIntegerLiteralTest, u64) {
+ EXPECT_EQ(uint64_t(0), 0_u64);
+ EXPECT_EQ(uint64_t(UINT8_MAX), 255_u64);
+ EXPECT_EQ(uint64_t(UINT8_MAX), 0xFF_u64);
+ EXPECT_EQ(uint64_t(UINT8_MAX), 0b11111111_u64);
+ EXPECT_EQ(uint64_t(UINT16_MAX), 65535_u64);
+ EXPECT_EQ(uint64_t(UINT16_MAX), 0xFFFF_u64);
+ EXPECT_EQ(uint64_t(UINT16_MAX), 0b11111111'11111111_u64);
+ EXPECT_EQ(uint64_t(UINT32_MAX), 4294967295_u64);
+ EXPECT_EQ(uint64_t(UINT32_MAX), 0xFFFFFFFF_u64);
+ EXPECT_EQ(uint64_t(UINT32_MAX), 0b1111111111111111'1111111111111111_u64);
+ EXPECT_EQ(uint64_t(UINT64_MAX), 18446744073709551615_u64);
+ EXPECT_EQ(uint64_t(UINT64_MAX), 0xFFFFFFFF'FFFFFFFF_u64);
+ EXPECT_EQ(
+ uint64_t(UINT64_MAX),
+ 0b1111111111111111'1111111111111111'1111111111111111'1111111111111111_u64);
+}
+
+TEST(LlvmLibcIntegerLiteralTest, u128) {
+#ifdef LIBC_TYPES_HAS_INT128
+ const __uint128_t ZERO = 0;
+ const __uint128_t U8_MAX = UINT8_MAX;
+ const __uint128_t U16_MAX = UINT16_MAX;
+ const __uint128_t U32_MAX = UINT32_MAX;
+ const __uint128_t U64_MAX = UINT64_MAX;
+ const __uint128_t U128_MAX = (U64_MAX << 64) | U64_MAX;
+#else
+ const UInt128 ZERO = 0;
+ const UInt128 U8_MAX = UINT8_MAX;
+ const UInt128 U16_MAX = UINT16_MAX;
+ const UInt128 U32_MAX = UINT32_MAX;
+ const UInt128 U64_MAX = UINT64_MAX;
+ const UInt128 U128_MAX = (U64_MAX << 64) | U64_MAX;
+#endif // LIBC_TYPES_HAS_INT128
+ EXPECT_EQ(ZERO, 0_u128);
+ EXPECT_EQ(U8_MAX, 255_u128);
+ EXPECT_EQ(U8_MAX, 0xFF_u128);
+ EXPECT_EQ(U8_MAX, 0b11111111_u128);
+ EXPECT_EQ(U16_MAX, 65535_u128);
+ EXPECT_EQ(U16_MAX, 0xFFFF_u128);
+ EXPECT_EQ(U16_MAX, 0b11111111'11111111_u128);
+ EXPECT_EQ(U32_MAX, 4294967295_u128);
+ EXPECT_EQ(U32_MAX, 0xFFFFFFFF_u128);
+ EXPECT_EQ(U32_MAX, 0b1111111111111111'1111111111111111_u128);
+ EXPECT_EQ(U64_MAX, 18446744073709551615_u128);
+ EXPECT_EQ(U64_MAX, 0xFFFFFFFF'FFFFFFFF_u128);
+ EXPECT_EQ(
+ U64_MAX,
+ 0b1111111111111111'1111111111111111'1111111111111111'1111111111111111_u128);
+ EXPECT_EQ(U128_MAX, 340282366920938463463374607431768211455_u128);
+ EXPECT_EQ(U128_MAX, 0xFFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF_u128);
+ EXPECT_EQ(
+ U128_MAX,
+ 0b1111111111111111'1111111111111111'1111111111111111'1111111111111111'1111111111111111'1111111111111111'1111111111111111'1111111111111111_u128);
+}
+
+TEST(LlvmLibcIntegerLiteralTest, u256) {
+ using UInt256 = LIBC_NAMESPACE::UInt<256>;
+ const UInt256 ZERO = 0;
+ const UInt256 U8_MAX = UINT8_MAX;
+ const UInt256 U16_MAX = UINT16_MAX;
+ const UInt256 U32_MAX = UINT32_MAX;
+ const UInt256 U64_MAX = UINT64_MAX;
+ const UInt256 U128_MAX = (U64_MAX << 64) | U64_MAX;
+ const UInt256 U256_MAX = (U128_MAX << 128) | U128_MAX;
+ EXPECT_EQ(ZERO, 0_u256);
+ EXPECT_EQ(U8_MAX, 255_u256);
+ EXPECT_EQ(U8_MAX, 0xFF_u256);
+ EXPECT_EQ(U8_MAX, 0b11111111_u256);
+ EXPECT_EQ(U16_MAX, 65535_u256);
+ EXPECT_EQ(U16_MAX, 0xFFFF_u256);
+ EXPECT_EQ(U16_MAX, 0b11111111'11111111_u256);
+ EXPECT_EQ(U32_MAX, 4294967295_u256);
+ EXPECT_EQ(U32_MAX, 0xFFFFFFFF_u256);
+ EXPECT_EQ(U32_MAX, 0b1111111111111111'1111111111111111_u256);
+ EXPECT_EQ(U64_MAX, 18446744073709551615_u256);
+ EXPECT_EQ(U64_MAX, 0xFFFFFFFF'FFFFFFFF_u256);
+ EXPECT_EQ(
+ U64_MAX,
+ 0b1111111111111111'1111111111111111'1111111111111111'1111111111111111_u256);
+ EXPECT_EQ(U128_MAX, 0xFFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF_u256);
+ EXPECT_EQ(
+ U256_MAX,
+ 0xFFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF_u256);
+}
+
+TEST(LlvmLibcIntegerLiteralTest, parse_bigint) {
+ using T = LIBC_NAMESPACE::Int<128>;
+ struct {
+ const char *str;
+ T expected;
+ } constexpr TEST_CASES[] = {
+ {"0", 0}, {"-1", -1}, {"+1", 1}, {"-0xFF", -255}, {"-0b11", -3},
+ };
+ for (auto tc : TEST_CASES) {
+ T actual = LIBC_NAMESPACE::parse_bigint<T>(tc.str);
+ EXPECT_EQ(actual, tc.expected);
+ }
+}
+
+TEST(LlvmLibcIntegerLiteralTest, parse_bigint_invalid) {
+ using T = LIBC_NAMESPACE::Int<128>;
+ const T expected{}; // default construction
+ EXPECT_EQ(LIBC_NAMESPACE::parse_bigint<T>(nullptr), expected);
+ EXPECT_EQ(LIBC_NAMESPACE::parse_bigint<T>(""), expected);
+}
>From 25a51076667c5dc4b7d0d15d6691156d2758650c Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 28 Jun 2026 01:54:22 +0530
Subject: [PATCH 09/44] big_int remaining
---
libc/src/__support/big_int.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/src/__support/big_int.h b/libc/src/__support/big_int.h
index 98bab6a7127ac..26af527dc2255 100644
--- a/libc/src/__support/big_int.h
+++ b/libc/src/__support/big_int.h
@@ -607,7 +607,7 @@ struct BigInt {
template <size_t OtherBits>
LIBC_INLINE constexpr auto
ful_mul(const BigInt<OtherBits, Signed, WordType> &other) const {
- BigInt<Bits + OtherBits, Signed, WordType> result;
+ BigInt<Bits + OtherBits, Signed, WordType> result{};
multiword::multiply_with_carry(result.val, val, other.val);
return result;
}
>From 639c4630b84107378432b26a5edffdb7a3c394f2 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 28 Jun 2026 12:38:20 +0530
Subject: [PATCH 10/44] bit_cast
---
libc/src/__support/big_int.h | 50 ++++++++++++++++++------------------
1 file changed, 25 insertions(+), 25 deletions(-)
diff --git a/libc/src/__support/big_int.h b/libc/src/__support/big_int.h
index 26af527dc2255..a23386214e21a 100644
--- a/libc/src/__support/big_int.h
+++ b/libc/src/__support/big_int.h
@@ -1186,31 +1186,31 @@ LIBC_INLINE_VAR constexpr bool is_unsigned_integral_or_big_int_v =
is_unsigned_integral_or_big_int<T>::value;
namespace cpp {
-// Temporarily disabled
-// // Specialization of cpp::bit_cast ('bit.h') from T to BigInt.
-// template <typename To, typename From>
-// LIBC_INLINE LIBC_BIT_CAST_CONSTEXPR cpp::enable_if_t<
-// (sizeof(To) == sizeof(From)) && cpp::is_trivially_copyable<To>::value &&
-// cpp::is_trivially_copyable<From>::value && is_big_int<To>::value,
-// To>
-// bit_cast(const From &from) {
-// To out;
-// using Storage = decltype(out.val);
-// out.val = cpp::bit_cast<Storage>(from);
-// return out;
-// }
-
-// // Specialization of cpp::bit_cast ('bit.h') from BigInt to T.
-// template <typename To, size_t Bits>
-// LIBC_INLINE LIBC_BIT_CAST_CONSTEXPR
-// cpp::enable_if_t<sizeof(To) == sizeof(UInt<Bits>) &&
-// cpp::is_trivially_constructible<To>::value &&
-// cpp::is_trivially_copyable<To>::value &&
-// cpp::is_trivially_copyable<UInt<Bits>>::value,
-// To>
-// bit_cast(const UInt<Bits> &from) {
-// return cpp::bit_cast<To>(from.val);
-// }
+
+// Specialization of cpp::bit_cast ('bit.h') from T to BigInt.
+template <typename To, typename From>
+LIBC_INLINE LIBC_BIT_CAST_CONSTEXPR cpp::enable_if_t<
+ (sizeof(To) == sizeof(From)) && cpp::is_trivially_copyable<To>::value &&
+ cpp::is_trivially_copyable<From>::value && is_big_int<To>::value,
+ To>
+bit_cast(const From &from) {
+ To out;
+ using Storage = decltype(out.val);
+ out.val = cpp::bit_cast<Storage>(from);
+ return out;
+}
+
+// Specialization of cpp::bit_cast ('bit.h') from BigInt to T.
+template <typename To, size_t Bits>
+LIBC_INLINE LIBC_BIT_CAST_CONSTEXPR
+ cpp::enable_if_t<sizeof(To) == sizeof(UInt<Bits>) &&
+ cpp::is_trivially_constructible<To>::value &&
+ cpp::is_trivially_copyable<To>::value &&
+ cpp::is_trivially_copyable<UInt<Bits>>::value,
+ To>
+ bit_cast(const UInt<Bits> &from) {
+ return cpp::bit_cast<To>(from.val);
+}
// Specialization of cpp::popcount ('bit.h') for BigInt.
template <typename T>
>From acd90189cbe68b116bd6d4c3f9a9a5aac505b609 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 28 Jun 2026 13:16:43 +0530
Subject: [PATCH 11/44] revert bit_cast
---
libc/src/__support/big_int.h | 48 ++++++++++++++++++------------------
1 file changed, 24 insertions(+), 24 deletions(-)
diff --git a/libc/src/__support/big_int.h b/libc/src/__support/big_int.h
index a23386214e21a..29feb0403966a 100644
--- a/libc/src/__support/big_int.h
+++ b/libc/src/__support/big_int.h
@@ -1187,30 +1187,30 @@ LIBC_INLINE_VAR constexpr bool is_unsigned_integral_or_big_int_v =
namespace cpp {
-// Specialization of cpp::bit_cast ('bit.h') from T to BigInt.
-template <typename To, typename From>
-LIBC_INLINE LIBC_BIT_CAST_CONSTEXPR cpp::enable_if_t<
- (sizeof(To) == sizeof(From)) && cpp::is_trivially_copyable<To>::value &&
- cpp::is_trivially_copyable<From>::value && is_big_int<To>::value,
- To>
-bit_cast(const From &from) {
- To out;
- using Storage = decltype(out.val);
- out.val = cpp::bit_cast<Storage>(from);
- return out;
-}
-
-// Specialization of cpp::bit_cast ('bit.h') from BigInt to T.
-template <typename To, size_t Bits>
-LIBC_INLINE LIBC_BIT_CAST_CONSTEXPR
- cpp::enable_if_t<sizeof(To) == sizeof(UInt<Bits>) &&
- cpp::is_trivially_constructible<To>::value &&
- cpp::is_trivially_copyable<To>::value &&
- cpp::is_trivially_copyable<UInt<Bits>>::value,
- To>
- bit_cast(const UInt<Bits> &from) {
- return cpp::bit_cast<To>(from.val);
-}
+// // Specialization of cpp::bit_cast ('bit.h') from T to BigInt.
+// template <typename To, typename From>
+// LIBC_INLINE LIBC_BIT_CAST_CONSTEXPR cpp::enable_if_t<
+// (sizeof(To) == sizeof(From)) && cpp::is_trivially_copyable<To>::value &&
+// cpp::is_trivially_copyable<From>::value && is_big_int<To>::value,
+// To>
+// bit_cast(const From &from) {
+// To out;
+// using Storage = decltype(out.val);
+// out.val = cpp::bit_cast<Storage>(from);
+// return out;
+// }
+
+// // Specialization of cpp::bit_cast ('bit.h') from BigInt to T.
+// template <typename To, size_t Bits>
+// LIBC_INLINE LIBC_BIT_CAST_CONSTEXPR
+// cpp::enable_if_t<sizeof(To) == sizeof(UInt<Bits>) &&
+// cpp::is_trivially_constructible<To>::value &&
+// cpp::is_trivially_copyable<To>::value &&
+// cpp::is_trivially_copyable<UInt<Bits>>::value,
+// To>
+// bit_cast(const UInt<Bits> &from) {
+// return cpp::bit_cast<To>(from.val);
+// }
// Specialization of cpp::popcount ('bit.h') for BigInt.
template <typename T>
>From cec2f0bafa6221c140e98aceabd44d4d2f5554fc Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 28 Jun 2026 23:41:01 +0530
Subject: [PATCH 12/44] clang-format
---
libc/src/__support/big_int.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libc/src/__support/big_int.h b/libc/src/__support/big_int.h
index 29feb0403966a..55768b6a8333e 100644
--- a/libc/src/__support/big_int.h
+++ b/libc/src/__support/big_int.h
@@ -857,8 +857,8 @@ struct BigInt {
result[i] = lhs[i] OP rhs[i]; \
return result; \
} \
- LIBC_INLINE friend constexpr BigInt operator OP##=(BigInt &lhs, \
- const BigInt &rhs) { \
+ LIBC_INLINE friend constexpr BigInt operator OP## = \
+ (BigInt & lhs, const BigInt &rhs) { \
for (size_t i = 0; i < WORD_COUNT; ++i) \
lhs[i] OP## = rhs[i]; \
return lhs; \
>From 274507fb133d505e7c824efb18d7ded59d9f37ec Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sat, 30 May 2026 02:08:42 +0530
Subject: [PATCH 13/44] test: float128 skeleton
---
libc/src/__support/FPUtil/CMakeLists.txt | 11 ++++++
libc/src/__support/FPUtil/float128.h | 45 ++++++++++++++++++++++++
2 files changed, 56 insertions(+)
create mode 100644 libc/src/__support/FPUtil/float128.h
diff --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt
index d45dd82560788..a88986b4992f8 100644
--- a/libc/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/src/__support/FPUtil/CMakeLists.txt
@@ -294,4 +294,15 @@ add_header_library(
libc.src.__support.macros.properties.types
)
+add_header_library(
+ float128
+ HDRS
+ float128.h
+ DEPENDS
+ .fp_bits
+ libc.hdr.fenv_macros
+ libc.src.__support.CPP.bit
+ libc.src.__support.uint128
+)
+
add_subdirectory(generic)
diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
new file mode 100644
index 0000000000000..73f450f1d41a8
--- /dev/null
+++ b/libc/src/__support/FPUtil/float128.h
@@ -0,0 +1,45 @@
+//===-- Utilities for Float128 data type -----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H
+#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H
+
+#include "FPBits.h"
+#include "hdr/fenv_macros.h"
+#include "src/__support/CPP/bit.h"
+#include "src/__support/uint128.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace fputil {
+
+struct Float128 {
+ UInt128 bits;
+ // Testing
+ constexpr Float128() = default;
+ /* TODO: precision
+ TODO: explicit so it does not convert without warn ( Done )
+ VERIFY : template <cpp::enable_if_t<fputil::get_fp_type<Double>() ==
+ fputil::FPType::IEEE754_Binary64,
+ int> = 0>
+ */
+ constexpr explicit Float128(double x) {
+ FPBits<double> x_bits(x);
+ uint64_t val = x_bits.uintval();
+ bits = static_cast<UInt128>(val) << 64;
+ }
+
+ constexpr explicit operator double() const {
+ uint64_t val = static_cast<uint64_t>(bits >> 64U);
+ return cpp::bit_cast<double>(val);
+ }
+};
+
+} // namespace fputil
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H
>From 2f05d78cb4a9b53b6cb971325283664afad196a0 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Tue, 2 Jun 2026 14:00:26 +0530
Subject: [PATCH 14/44] Add small smoke test
---
.../CPP/type_traits/is_floating_point.h | 2 +-
libc/src/__support/FPUtil/CMakeLists.txt | 4 +-
libc/src/__support/FPUtil/FPBits.h | 13 +++++-
libc/src/__support/FPUtil/float128.h | 41 +++++++++++--------
libc/src/__support/macros/properties/types.h | 8 ++++
libc/test/src/math/smoke/CMakeLists.txt | 10 +++++
libc/test/src/math/smoke/float128_test.cpp | 25 +++++++++++
7 files changed, 81 insertions(+), 22 deletions(-)
create mode 100644 libc/test/src/math/smoke/float128_test.cpp
diff --git a/libc/src/__support/CPP/type_traits/is_floating_point.h b/libc/src/__support/CPP/type_traits/is_floating_point.h
index 9dc77ad7ee0ea..ab4191868517e 100644
--- a/libc/src/__support/CPP/type_traits/is_floating_point.h
+++ b/libc/src/__support/CPP/type_traits/is_floating_point.h
@@ -37,7 +37,7 @@ template <typename T> struct is_floating_point {
float128
#endif
,
- bfloat16>();
+ bfloat16, fputil::Float128>();
};
template <typename T>
LIBC_INLINE_VAR constexpr bool is_floating_point_v =
diff --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt
index a88986b4992f8..20e1c01bb8ca1 100644
--- a/libc/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/src/__support/FPUtil/CMakeLists.txt
@@ -299,9 +299,9 @@ add_header_library(
HDRS
float128.h
DEPENDS
- .fp_bits
- libc.hdr.fenv_macros
libc.src.__support.CPP.bit
+ libc.src.__support.macros.attributes
+ libc.src.__support.macros.config
libc.src.__support.uint128
)
diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index c52699e17e225..5b7461a44cff5 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -37,7 +37,8 @@ enum class FPType {
IEEE754_Binary64,
IEEE754_Binary128,
X86_Binary80,
- BFloat16
+ BFloat16,
+ Float128
};
// The classes hierarchy is as follows:
@@ -146,6 +147,14 @@ template <> struct FPLayout<FPType::BFloat16> {
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = SIG_LEN;
};
+template <> struct FPLayout<FPType::Float128> {
+ using StorageType = UInt128;
+ LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
+ LIBC_INLINE_VAR static constexpr int EXP_LEN = 15;
+ LIBC_INLINE_VAR static constexpr int SIG_LEN = 112;
+ LIBC_INLINE_VAR static constexpr int FRACTION_LEN = SIG_LEN;
+};
+
// FPStorage derives useful constants from the FPLayout above.
template <FPType fp_type> struct FPStorage : public FPLayout<fp_type> {
using UP = FPLayout<fp_type>;
@@ -813,6 +822,8 @@ template <typename T> LIBC_INLINE static constexpr FPType get_fp_type() {
#endif
else if constexpr (cpp::is_same_v<UnqualT, bfloat16>)
return FPType::BFloat16;
+ else if constexpr (cpp::is_same_v<UnqualT, Float128>)
+ return FPType::Float128;
else
static_assert(cpp::always_false<UnqualT>, "Unsupported type");
}
diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index 73f450f1d41a8..ca5c49ddf11d7 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -1,4 +1,8 @@
+<<<<<<< HEAD
//===-- Utilities for Float128 data type -----------------------*- C++ -*-===//
+=======
+//===-- Definition for Float128 data type -----------------------*- C++ -*-===//
+>>>>>>> f128-test
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -9,33 +13,34 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H
#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H
-#include "FPBits.h"
-#include "hdr/fenv_macros.h"
-#include "src/__support/CPP/bit.h"
+#include "src/__support/CPP/bit.h" // cpp::bit_cast
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
#include "src/__support/uint128.h"
+#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
namespace fputil {
struct Float128 {
UInt128 bits;
- // Testing
- constexpr Float128() = default;
- /* TODO: precision
- TODO: explicit so it does not convert without warn ( Done )
- VERIFY : template <cpp::enable_if_t<fputil::get_fp_type<Double>() ==
- fputil::FPType::IEEE754_Binary64,
- int> = 0>
- */
- constexpr explicit Float128(double x) {
- FPBits<double> x_bits(x);
- uint64_t val = x_bits.uintval();
- bits = static_cast<UInt128>(val) << 64;
+
+ LIBC_INLINE Float128() = default;
+
+ LIBC_INLINE constexpr explicit Float128(double x) : bits(0) {
+ uint64_t d = cpp::bit_cast<uint64_t>(x);
+ bits = static_cast<UInt128>(d) << 64U;
}
- constexpr explicit operator double() const {
- uint64_t val = static_cast<uint64_t>(bits >> 64U);
- return cpp::bit_cast<double>(val);
+ LIBC_INLINE constexpr explicit operator double() const {
+ return cpp::bit_cast<double>(static_cast<uint64_t>(bits >> 64U));
+ }
+
+ LIBC_INLINE constexpr bool operator==(Float128 other) const {
+ return bits == other.bits;
+ }
+ LIBC_INLINE constexpr bool operator!=(Float128 other) const {
+ return bits != other.bits;
}
};
diff --git a/libc/src/__support/macros/properties/types.h b/libc/src/__support/macros/properties/types.h
index 3259c8a6a1d12..d94f6068984df 100644
--- a/libc/src/__support/macros/properties/types.h
+++ b/libc/src/__support/macros/properties/types.h
@@ -58,6 +58,14 @@ using float16 = _Float16;
// LIBC_TYPES_HAS_FLOAT128 and 'float128' type are provided by
// "include/llvm-libc-types/float128.h"
+// -- Emulated float128 support ------------------------------------------------
+// Float128 is always available regardless of native __float128 support.
+namespace LIBC_NAMESPACE_DECL {
+namespace fputil {
+struct Float128;
+}
+} // namespace LIBC_NAMESPACE_DECL
+
// -- bfloat16 support ---------------------------------------------------------
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index e4e2fb11438d4..3081a62552c49 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -1,6 +1,16 @@
add_custom_target(libc-math-smoke-tests)
add_dependencies(libc-math-unittests libc-math-smoke-tests)
+add_libc_unittest(
+ float128_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ float128_test.cpp
+ DEPENDS
+ libc.src.__support.FPUtil.float128
+)
+
add_fp_unittest(
cosf_test
SUITE
diff --git a/libc/test/src/math/smoke/float128_test.cpp b/libc/test/src/math/smoke/float128_test.cpp
new file mode 100644
index 0000000000000..738e5ec703f00
--- /dev/null
+++ b/libc/test/src/math/smoke/float128_test.cpp
@@ -0,0 +1,25 @@
+//===-- Unittests for Float128 emulated type -----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/FPUtil/float128.h"
+#include "src/__support/uint128.h"
+#include "test/UnitTest/Test.h"
+
+using LIBC_NAMESPACE::fputil::Float128;
+
+TEST(LlvmLibcFloat128Test, DefaultConstructor) {
+ Float128 x;
+ (void)x;
+}
+
+TEST(LlvmLibcFloat128Test, Equality) {
+ Float128 a(1.0), b(1.0), c(2.0);
+ ASSERT_TRUE(a == b);
+ ASSERT_TRUE(a != c);
+ ASSERT_TRUE(b != c);
+}
>From 5588bbf2f28f274e90c9070d2b27e331dd9ce515 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Tue, 2 Jun 2026 14:06:05 +0530
Subject: [PATCH 15/44] nit
---
libc/src/__support/FPUtil/float128.h | 4 ----
1 file changed, 4 deletions(-)
diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index ca5c49ddf11d7..c7835d7376853 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -1,8 +1,4 @@
-<<<<<<< HEAD
-//===-- Utilities for Float128 data type -----------------------*- C++ -*-===//
-=======
//===-- Definition for Float128 data type -----------------------*- C++ -*-===//
->>>>>>> f128-test
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
>From 0669aa4212f5589eb9b04a326ca6366e29a82c57 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Tue, 2 Jun 2026 15:13:25 +0530
Subject: [PATCH 16/44] nit
---
libc/src/__support/FPUtil/float128.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index c7835d7376853..cc72692e8a22f 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -9,7 +9,7 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H
#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H
-#include "src/__support/CPP/bit.h" // cpp::bit_cast
+#include "src/__support/CPP/bit.h"
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
#include "src/__support/uint128.h"
@@ -24,8 +24,8 @@ struct Float128 {
LIBC_INLINE Float128() = default;
LIBC_INLINE constexpr explicit Float128(double x) : bits(0) {
- uint64_t d = cpp::bit_cast<uint64_t>(x);
- bits = static_cast<UInt128>(d) << 64U;
+ uint64_t x_bits = cpp::bit_cast<uint64_t>(x);
+ bits = static_cast<UInt128>(x_bits) << 64U;
}
LIBC_INLINE constexpr explicit operator double() const {
>From 97a873f2c26cd8d3e01ce5c2a6b1e19476ff3829 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Tue, 2 Jun 2026 20:52:36 +0530
Subject: [PATCH 17/44] temp commit for rebase
---
libc/src/__support/CPP/type_traits/is_floating_point.h | 5 ++++-
libc/src/__support/FPUtil/cast.h | 4 +++-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/libc/src/__support/CPP/type_traits/is_floating_point.h b/libc/src/__support/CPP/type_traits/is_floating_point.h
index ab4191868517e..d53dcd4961ab6 100644
--- a/libc/src/__support/CPP/type_traits/is_floating_point.h
+++ b/libc/src/__support/CPP/type_traits/is_floating_point.h
@@ -37,7 +37,10 @@ template <typename T> struct is_floating_point {
float128
#endif
,
- bfloat16, fputil::Float128>();
+ bfloat16
+
+ ,
+ fputil::Float128>();
};
template <typename T>
LIBC_INLINE_VAR constexpr bool is_floating_point_v =
diff --git a/libc/src/__support/FPUtil/cast.h b/libc/src/__support/FPUtil/cast.h
index 54c80e862523a..4fc5ea0893ebe 100644
--- a/libc/src/__support/FPUtil/cast.h
+++ b/libc/src/__support/FPUtil/cast.h
@@ -31,7 +31,9 @@ cast(InType x) {
return x;
} else {
if constexpr (cpp::is_same_v<OutType, bfloat16> ||
- cpp::is_same_v<InType, bfloat16>
+ cpp::is_same_v<InType, bfloat16> ||
+ cpp::is_same_v<OutType, Float128> ||
+ cpp::is_same_v<InType, Float128>
#if defined(LIBC_TYPES_HAS_FLOAT16) && !defined(__LIBC_USE_FLOAT16_CONVERSION)
|| cpp::is_same_v<OutType, float16> ||
cpp::is_same_v<InType, float16>
>From 0edf50d1786c959c3c58e12454583fcfe5de3241 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Tue, 2 Jun 2026 22:24:48 +0530
Subject: [PATCH 18/44] feat: comparison operator overload
---
libc/src/__support/FPUtil/CMakeLists.txt | 2 ++
libc/src/__support/FPUtil/cast.h | 4 ++--
libc/src/__support/FPUtil/dyadic_float.h | 2 +-
libc/src/__support/FPUtil/float128.h | 23 ++++++++++++++++++--
libc/src/__support/macros/properties/types.h | 3 +++
libc/test/src/math/smoke/float128_test.cpp | 8 ++++++-
6 files changed, 36 insertions(+), 6 deletions(-)
diff --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt
index 20e1c01bb8ca1..c49d873b026e2 100644
--- a/libc/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/src/__support/FPUtil/CMakeLists.txt
@@ -303,6 +303,8 @@ add_header_library(
libc.src.__support.macros.attributes
libc.src.__support.macros.config
libc.src.__support.uint128
+ libc.src.__support.CPP.type_traits
+ .comparison_operations
)
add_subdirectory(generic)
diff --git a/libc/src/__support/FPUtil/cast.h b/libc/src/__support/FPUtil/cast.h
index 4fc5ea0893ebe..e7b2caf92fe4a 100644
--- a/libc/src/__support/FPUtil/cast.h
+++ b/libc/src/__support/FPUtil/cast.h
@@ -32,8 +32,8 @@ cast(InType x) {
} else {
if constexpr (cpp::is_same_v<OutType, bfloat16> ||
cpp::is_same_v<InType, bfloat16> ||
- cpp::is_same_v<OutType, Float128> ||
- cpp::is_same_v<InType, Float128>
+ cpp::is_same_v<OutType, float128> ||
+ cpp::is_same_v<InType, float128>
#if defined(LIBC_TYPES_HAS_FLOAT16) && !defined(__LIBC_USE_FLOAT16_CONVERSION)
|| cpp::is_same_v<OutType, float16> ||
cpp::is_same_v<InType, float16>
diff --git a/libc/src/__support/FPUtil/dyadic_float.h b/libc/src/__support/FPUtil/dyadic_float.h
index f1ac39e97c52b..95e990554210c 100644
--- a/libc/src/__support/FPUtil/dyadic_float.h
+++ b/libc/src/__support/FPUtil/dyadic_float.h
@@ -438,7 +438,7 @@ template <size_t Bits> struct DyadicFloat {
(FPBits<T>::FRACTION_LEN < Bits),
void>>
LIBC_INLINE LIBC_CONSTEXPR_DEFAULT T as() const {
- if constexpr (cpp::is_same_v<T, bfloat16>
+ if constexpr (cpp::is_same_v<T, bfloat16> || cpp::is_same_v<T, float128>
#if defined(LIBC_TYPES_HAS_FLOAT16) && !defined(__LIBC_USE_FLOAT16_CONVERSION)
|| cpp::is_same_v<T, float16>
#endif
diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index cc72692e8a22f..d887153f58afb 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -10,6 +10,8 @@
#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H
#include "src/__support/CPP/bit.h"
+#include "src/__support/CPP/type_traits.h"
+#include "src/__support/FPUtil/comparison_operations.h"
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
#include "src/__support/uint128.h"
@@ -33,10 +35,27 @@ struct Float128 {
}
LIBC_INLINE constexpr bool operator==(Float128 other) const {
- return bits == other.bits;
+ return fputil::equals(*this, other);
}
+
LIBC_INLINE constexpr bool operator!=(Float128 other) const {
- return bits != other.bits;
+ return !fputil::equals(*this, other);
+ }
+
+ LIBC_INLINE constexpr bool operator<(Float128 other) const {
+ return fputil::less_than(*this, other);
+ }
+
+ LIBC_INLINE constexpr bool operator<=(Float128 other) const {
+ return fputil::less_than_or_equals(*this, other);
+ }
+
+ LIBC_INLINE constexpr bool operator>(Float128 other) const {
+ return fputil::greater_than(*this, other);
+ }
+
+ LIBC_INLINE constexpr bool operator>=(Float128 other) const {
+ return fputil::greater_than_or_equals(*this, other);
}
};
diff --git a/libc/src/__support/macros/properties/types.h b/libc/src/__support/macros/properties/types.h
index d94f6068984df..02d08867a4c9f 100644
--- a/libc/src/__support/macros/properties/types.h
+++ b/libc/src/__support/macros/properties/types.h
@@ -66,6 +66,9 @@ struct Float128;
}
} // namespace LIBC_NAMESPACE_DECL
+#ifndef LIBC_TYPES_HAS_FLOAT128
+using float128 = LIBC_NAMESPACE::fputil::Float128;
+#endif // LIBC_TYPES_HAS_FLOAT128
// -- bfloat16 support ---------------------------------------------------------
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/test/src/math/smoke/float128_test.cpp b/libc/test/src/math/smoke/float128_test.cpp
index 738e5ec703f00..29fcc73384fd5 100644
--- a/libc/test/src/math/smoke/float128_test.cpp
+++ b/libc/test/src/math/smoke/float128_test.cpp
@@ -17,9 +17,15 @@ TEST(LlvmLibcFloat128Test, DefaultConstructor) {
(void)x;
}
-TEST(LlvmLibcFloat128Test, Equality) {
+TEST(LlvmLibcFloat128Test, operators) {
Float128 a(1.0), b(1.0), c(2.0);
+
+ // comparison operators
ASSERT_TRUE(a == b);
ASSERT_TRUE(a != c);
ASSERT_TRUE(b != c);
+ ASSERT_TRUE(c > b);
+ ASSERT_TRUE(a >= b);
+ ASSERT_TRUE(b <= c);
+ ASSERT_TRUE(a < c);
}
>From 7d1a5097f2f46a5c2169f373de0d55f7ce129939 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Wed, 3 Jun 2026 00:02:22 +0530
Subject: [PATCH 19/44] marking default const , constexpr
---
libc/src/__support/FPUtil/float128.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index d887153f58afb..c9db7fd683bd1 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -23,7 +23,7 @@ namespace fputil {
struct Float128 {
UInt128 bits;
- LIBC_INLINE Float128() = default;
+ LIBC_INLINE constexpr Float128() = default;
LIBC_INLINE constexpr explicit Float128(double x) : bits(0) {
uint64_t x_bits = cpp::bit_cast<uint64_t>(x);
>From 83611b0e0db65de081e3a16c3111c467a48ca0ec Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Wed, 3 Jun 2026 01:02:42 +0530
Subject: [PATCH 20/44] testing alias + removed constexpr for def const
---
libc/src/__support/FPUtil/cast.h | 4 ++--
libc/src/__support/FPUtil/dyadic_float.h | 2 +-
libc/src/__support/FPUtil/float128.h | 2 +-
libc/src/__support/macros/properties/types.h | 6 +++---
4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/libc/src/__support/FPUtil/cast.h b/libc/src/__support/FPUtil/cast.h
index e7b2caf92fe4a..4fc5ea0893ebe 100644
--- a/libc/src/__support/FPUtil/cast.h
+++ b/libc/src/__support/FPUtil/cast.h
@@ -32,8 +32,8 @@ cast(InType x) {
} else {
if constexpr (cpp::is_same_v<OutType, bfloat16> ||
cpp::is_same_v<InType, bfloat16> ||
- cpp::is_same_v<OutType, float128> ||
- cpp::is_same_v<InType, float128>
+ cpp::is_same_v<OutType, Float128> ||
+ cpp::is_same_v<InType, Float128>
#if defined(LIBC_TYPES_HAS_FLOAT16) && !defined(__LIBC_USE_FLOAT16_CONVERSION)
|| cpp::is_same_v<OutType, float16> ||
cpp::is_same_v<InType, float16>
diff --git a/libc/src/__support/FPUtil/dyadic_float.h b/libc/src/__support/FPUtil/dyadic_float.h
index 95e990554210c..c218632131934 100644
--- a/libc/src/__support/FPUtil/dyadic_float.h
+++ b/libc/src/__support/FPUtil/dyadic_float.h
@@ -438,7 +438,7 @@ template <size_t Bits> struct DyadicFloat {
(FPBits<T>::FRACTION_LEN < Bits),
void>>
LIBC_INLINE LIBC_CONSTEXPR_DEFAULT T as() const {
- if constexpr (cpp::is_same_v<T, bfloat16> || cpp::is_same_v<T, float128>
+ if constexpr (cpp::is_same_v<T, bfloat16> || cpp::is_same_v<T, Float128>
#if defined(LIBC_TYPES_HAS_FLOAT16) && !defined(__LIBC_USE_FLOAT16_CONVERSION)
|| cpp::is_same_v<T, float16>
#endif
diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index c9db7fd683bd1..d887153f58afb 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -23,7 +23,7 @@ namespace fputil {
struct Float128 {
UInt128 bits;
- LIBC_INLINE constexpr Float128() = default;
+ LIBC_INLINE Float128() = default;
LIBC_INLINE constexpr explicit Float128(double x) : bits(0) {
uint64_t x_bits = cpp::bit_cast<uint64_t>(x);
diff --git a/libc/src/__support/macros/properties/types.h b/libc/src/__support/macros/properties/types.h
index 02d08867a4c9f..7b861640c785d 100644
--- a/libc/src/__support/macros/properties/types.h
+++ b/libc/src/__support/macros/properties/types.h
@@ -66,9 +66,9 @@ struct Float128;
}
} // namespace LIBC_NAMESPACE_DECL
-#ifndef LIBC_TYPES_HAS_FLOAT128
-using float128 = LIBC_NAMESPACE::fputil::Float128;
-#endif // LIBC_TYPES_HAS_FLOAT128
+// #ifndef LIBC_TYPES_HAS_FLOAT128
+// using float128 = LIBC_NAMESPACE::fputil::Float128;
+// #endif // LIBC_TYPES_HAS_FLOAT128
// -- bfloat16 support ---------------------------------------------------------
namespace LIBC_NAMESPACE_DECL {
>From dbe21a0b5d1e9fdb99accda2cd5eb02efeebe02f Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Wed, 3 Jun 2026 13:40:43 +0530
Subject: [PATCH 21/44] template + LIBC_CONSTEXPR_DEFAULT
---
libc/src/__support/FPUtil/float128.h | 30 ++++++++++++++++------------
1 file changed, 17 insertions(+), 13 deletions(-)
diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index d887153f58afb..97c0daf79c546 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -9,8 +9,8 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H
#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H
-#include "src/__support/CPP/bit.h"
#include "src/__support/CPP/type_traits.h"
+#include "src/__support/FPUtil/cast.h"
#include "src/__support/FPUtil/comparison_operations.h"
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
@@ -25,36 +25,40 @@ struct Float128 {
LIBC_INLINE Float128() = default;
- LIBC_INLINE constexpr explicit Float128(double x) : bits(0) {
- uint64_t x_bits = cpp::bit_cast<uint64_t>(x);
- bits = static_cast<UInt128>(x_bits) << 64U;
+ template <typename T> LIBC_INLINE constexpr explicit Float128(T x) : bits(0) {
+ if constexpr (cpp::is_floating_point_v<T>) {
+ bits = fputil::cast<Float128>(x).bits;
+ }
+ // TODO: add rem after testing
}
- LIBC_INLINE constexpr explicit operator double() const {
- return cpp::bit_cast<double>(static_cast<uint64_t>(bits >> 64U));
+ template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T> &&
+ !cpp::is_same_v<T, Float128>,
+ int> = 0>
+ LIBC_INLINE LIBC_CONSTEXPR_DEFAULT operator T() const {
+ return fputil::cast<T>(*this);
}
-
- LIBC_INLINE constexpr bool operator==(Float128 other) const {
+ LIBC_INLINE constexpr bool operator==(Float128 &other) const {
return fputil::equals(*this, other);
}
- LIBC_INLINE constexpr bool operator!=(Float128 other) const {
+ LIBC_INLINE constexpr bool operator!=(Float128 &other) const {
return !fputil::equals(*this, other);
}
- LIBC_INLINE constexpr bool operator<(Float128 other) const {
+ LIBC_INLINE constexpr bool operator<(Float128 &other) const {
return fputil::less_than(*this, other);
}
- LIBC_INLINE constexpr bool operator<=(Float128 other) const {
+ LIBC_INLINE constexpr bool operator<=(Float128 &other) const {
return fputil::less_than_or_equals(*this, other);
}
- LIBC_INLINE constexpr bool operator>(Float128 other) const {
+ LIBC_INLINE constexpr bool operator>(Float128 &other) const {
return fputil::greater_than(*this, other);
}
- LIBC_INLINE constexpr bool operator>=(Float128 other) const {
+ LIBC_INLINE constexpr bool operator>=(Float128 &other) const {
return fputil::greater_than_or_equals(*this, other);
}
};
>From 7884075beab11dcd62ad7a6b6fd97ed7d1db14da Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 4 Jun 2026 20:34:00 +0530
Subject: [PATCH 22/44] testing double?
---
libc/test/src/math/smoke/float128_test.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/test/src/math/smoke/float128_test.cpp b/libc/test/src/math/smoke/float128_test.cpp
index 29fcc73384fd5..f2f6d31007754 100644
--- a/libc/test/src/math/smoke/float128_test.cpp
+++ b/libc/test/src/math/smoke/float128_test.cpp
@@ -18,7 +18,7 @@ TEST(LlvmLibcFloat128Test, DefaultConstructor) {
}
TEST(LlvmLibcFloat128Test, operators) {
- Float128 a(1.0), b(1.0), c(2.0);
+ Float128 a(1.0f), b(1.0f), c(2.0f);
// comparison operators
ASSERT_TRUE(a == b);
>From b27b35eea3351fa6040b8b8bb99600b9da306850 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 4 Jun 2026 21:49:40 +0530
Subject: [PATCH 23/44] test static assert
---
libc/src/__support/FPUtil/bfloat16.h | 7 +++++++
libc/src/__support/FPUtil/float128.h | 7 +++++++
2 files changed, 14 insertions(+)
diff --git a/libc/src/__support/FPUtil/bfloat16.h b/libc/src/__support/FPUtil/bfloat16.h
index ce4e3160a0963..cf3fefe75bff3 100644
--- a/libc/src/__support/FPUtil/bfloat16.h
+++ b/libc/src/__support/FPUtil/bfloat16.h
@@ -135,4 +135,11 @@ struct BFloat16 {
} // namespace fputil
} // namespace LIBC_NAMESPACE_DECL
+static_assert(
+ LIBC_NAMESPACE::cpp::is_trivially_constructible<
+ LIBC_NAMESPACE::fputil::BFloat16>::value);
+static_assert(
+ LIBC_NAMESPACE::cpp::is_trivially_copyable<
+ LIBC_NAMESPACE::fputil::BFloat16>::value);
+
#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_BFLOAT16_H
diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index 97c0daf79c546..184cc802d094d 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -66,4 +66,11 @@ struct Float128 {
} // namespace fputil
} // namespace LIBC_NAMESPACE_DECL
+static_assert(
+ LIBC_NAMESPACE::cpp::is_trivially_constructible<
+ LIBC_NAMESPACE::fputil::Float128>::value);
+static_assert(
+ LIBC_NAMESPACE::cpp::is_trivially_copyable<
+ LIBC_NAMESPACE::fputil::Float128>::value);
+
#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H
>From bc02145df3825ddd44afeb1ccc13c1a22d17b66e Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 4 Jun 2026 22:16:53 +0530
Subject: [PATCH 24/44] testing with all types of constructor
---
libc/src/__support/FPUtil/float128.h | 31 ++++++++++++++++++++++++----
1 file changed, 27 insertions(+), 4 deletions(-)
diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index 184cc802d094d..cf1a1d2f59199 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -23,13 +23,36 @@ namespace fputil {
struct Float128 {
UInt128 bits;
- LIBC_INLINE Float128() = default;
+ LIBC_INLINE constexpr Float128() = default;
+ LIBC_INLINE constexpr Float128(const Float128 &) = default;
+ LIBC_INLINE constexpr Float128(Float128 &&) = default;
+ LIBC_INLINE constexpr Float128 &operator=(const Float128 &) = default;
+ LIBC_INLINE constexpr Float128 &operator=(Float128 &&) = default;
- template <typename T> LIBC_INLINE constexpr explicit Float128(T x) : bits(0) {
+ template <typename T>
+ LIBC_INLINE constexpr explicit Float128(T value)
+ : bits(static_cast<UInt128>(0U)) {
if constexpr (cpp::is_floating_point_v<T>) {
- bits = fputil::cast<Float128>(x).bits;
+ bits = fputil::cast<Float128>(value).bits;
+ } else if constexpr (cpp::is_integral_v<T>) {
+ Sign sign = Sign::POS;
+
+ if constexpr (cpp::is_signed_v<T>) {
+ if (value < 0) {
+ sign = Sign::NEG;
+ value = -value;
+ }
+ }
+
+ fputil::DyadicFloat<cpp::numeric_limits<cpp::make_unsigned_t<T>>::digits>
+ xd(sign, 0, value);
+ bits = xd.template as<Float128, /*ShouldSignalExceptions=*/true>().bits;
+
+ } else if constexpr (cpp::is_convertible_v<T, Float128>) {
+ bits = value.operator Float128().bits;
+ } else {
+ bits = fputil::cast<Float128>(static_cast<float>(value)).bits;
}
- // TODO: add rem after testing
}
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T> &&
>From de1b66e8b25f36f46b558f93b8ac1e7f5f580a91 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 4 Jun 2026 22:24:42 +0530
Subject: [PATCH 25/44] removing constexpr
---
libc/src/__support/FPUtil/float128.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index cf1a1d2f59199..e8cccd019d0ea 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -23,7 +23,7 @@ namespace fputil {
struct Float128 {
UInt128 bits;
- LIBC_INLINE constexpr Float128() = default;
+ LIBC_INLINE Float128() = default;
LIBC_INLINE constexpr Float128(const Float128 &) = default;
LIBC_INLINE constexpr Float128(Float128 &&) = default;
LIBC_INLINE constexpr Float128 &operator=(const Float128 &) = default;
>From 6c48a9f605bfdc21ad7999a2eba9f880d029e639 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 11 Jun 2026 18:11:24 +0530
Subject: [PATCH 26/44] nits before final (Win fail)
---
libc/src/__support/CPP/type_traits/is_floating_point.h | 2 ++
libc/src/__support/FPUtil/bfloat16.h | 2 ++
libc/src/__support/FPUtil/float128.h | 3 ++-
3 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/libc/src/__support/CPP/type_traits/is_floating_point.h b/libc/src/__support/CPP/type_traits/is_floating_point.h
index d53dcd4961ab6..b7fa71bde2f93 100644
--- a/libc/src/__support/CPP/type_traits/is_floating_point.h
+++ b/libc/src/__support/CPP/type_traits/is_floating_point.h
@@ -40,6 +40,8 @@ template <typename T> struct is_floating_point {
bfloat16
,
+ // TODO: Replace as float128 once the alias is
+ // fixed
fputil::Float128>();
};
template <typename T>
diff --git a/libc/src/__support/FPUtil/bfloat16.h b/libc/src/__support/FPUtil/bfloat16.h
index cf3fefe75bff3..8a3f3c9894aad 100644
--- a/libc/src/__support/FPUtil/bfloat16.h
+++ b/libc/src/__support/FPUtil/bfloat16.h
@@ -135,11 +135,13 @@ struct BFloat16 {
} // namespace fputil
} // namespace LIBC_NAMESPACE_DECL
+// <--To be removed------------------------------------>
static_assert(
LIBC_NAMESPACE::cpp::is_trivially_constructible<
LIBC_NAMESPACE::fputil::BFloat16>::value);
static_assert(
LIBC_NAMESPACE::cpp::is_trivially_copyable<
LIBC_NAMESPACE::fputil::BFloat16>::value);
+// ----------------------------------------------------
#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_BFLOAT16_H
diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index e8cccd019d0ea..df1e3e5e884a7 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -89,11 +89,12 @@ struct Float128 {
} // namespace fputil
} // namespace LIBC_NAMESPACE_DECL
+// <--To be removed------------------------------------>
static_assert(
LIBC_NAMESPACE::cpp::is_trivially_constructible<
LIBC_NAMESPACE::fputil::Float128>::value);
static_assert(
LIBC_NAMESPACE::cpp::is_trivially_copyable<
LIBC_NAMESPACE::fputil::Float128>::value);
-
+// ----------------------------------------------------
#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H
>From 1d9f1286fbdaafe992f53156830d10bda1ebb444 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 11 Jun 2026 20:16:12 +0530
Subject: [PATCH 27/44] testing CI for more operators and conversions (
floating-type)
---
libc/src/__support/FPUtil/float128.h | 42 ++++++++++++++++++----
libc/test/src/math/smoke/float128_test.cpp | 16 ++++++++-
2 files changed, 51 insertions(+), 7 deletions(-)
diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index df1e3e5e884a7..663d54a8de01e 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -16,6 +16,11 @@
#include "src/__support/macros/config.h"
#include "src/__support/uint128.h"
#include <stdint.h>
+#include "hdr/stdint_proxy.h"
+#include "src/__support/FPUtil/dyadic_float.h"
+#include "src/__support/FPUtil/generic/add_sub.h"
+#include "src/__support/FPUtil/generic/div.h"
+#include "src/__support/FPUtil/generic/mul.h"
namespace LIBC_NAMESPACE_DECL {
namespace fputil {
@@ -29,6 +34,7 @@ struct Float128 {
LIBC_INLINE constexpr Float128 &operator=(const Float128 &) = default;
LIBC_INLINE constexpr Float128 &operator=(Float128 &&) = default;
+ // Floating point type and integer type
template <typename T>
LIBC_INLINE constexpr explicit Float128(T value)
: bits(static_cast<UInt128>(0U)) {
@@ -61,27 +67,51 @@ struct Float128 {
LIBC_INLINE LIBC_CONSTEXPR_DEFAULT operator T() const {
return fputil::cast<T>(*this);
}
- LIBC_INLINE constexpr bool operator==(Float128 &other) const {
+// TODO: Integer conversion
+ // unary
+ LIBC_INLINE LIBC_BIT_CAST_CONSTEXPR Float128 operator-() const {
+ fputil::FPBits<Float128> result(*this);
+ result.set_sign(result.is_pos() ? Sign::NEG : Sign::POS);
+ return result.get_val();
+ }
+ // operator overloads
+ LIBC_INLINE constexpr Float128 operator+(const Float128 &other) const {
+ return fputil::generic::add<Float128>(*this, other);
+ }
+
+ LIBC_INLINE constexpr Float128 operator-(const Float128 &other) const {
+ return fputil::generic::sub<Float128>(*this, other);
+ }
+
+ LIBC_INLINE constexpr Float128 operator*(const Float128 &other) const {
+ return fputil::generic::mul<Float128>(*this, other);
+ }
+
+ LIBC_INLINE constexpr Float128 operator/(const Float128 &other) const {
+ return fputil::generic::div<Float128>(*this, other);
+ }
+
+ LIBC_INLINE constexpr bool operator==(const Float128 &other) const {
return fputil::equals(*this, other);
}
- LIBC_INLINE constexpr bool operator!=(Float128 &other) const {
+ LIBC_INLINE constexpr bool operator!=(const Float128 &other) const {
return !fputil::equals(*this, other);
}
- LIBC_INLINE constexpr bool operator<(Float128 &other) const {
+ LIBC_INLINE constexpr bool operator<(const Float128 &other) const {
return fputil::less_than(*this, other);
}
- LIBC_INLINE constexpr bool operator<=(Float128 &other) const {
+ LIBC_INLINE constexpr bool operator<=(const Float128 &other) const {
return fputil::less_than_or_equals(*this, other);
}
- LIBC_INLINE constexpr bool operator>(Float128 &other) const {
+ LIBC_INLINE constexpr bool operator>(const Float128 &other) const {
return fputil::greater_than(*this, other);
}
- LIBC_INLINE constexpr bool operator>=(Float128 &other) const {
+ LIBC_INLINE constexpr bool operator>=(const Float128 &other) const {
return fputil::greater_than_or_equals(*this, other);
}
};
diff --git a/libc/test/src/math/smoke/float128_test.cpp b/libc/test/src/math/smoke/float128_test.cpp
index f2f6d31007754..1a3a9a6c45726 100644
--- a/libc/test/src/math/smoke/float128_test.cpp
+++ b/libc/test/src/math/smoke/float128_test.cpp
@@ -17,15 +17,29 @@ TEST(LlvmLibcFloat128Test, DefaultConstructor) {
(void)x;
}
-TEST(LlvmLibcFloat128Test, operators) {
+TEST(LlvmLibcFloat128Test, UnaryOperators) {
Float128 a(1.0f), b(1.0f), c(2.0f);
// comparison operators
ASSERT_TRUE(a == b);
+ ASSERT_TRUE(a == Float128(1.0));
ASSERT_TRUE(a != c);
ASSERT_TRUE(b != c);
ASSERT_TRUE(c > b);
ASSERT_TRUE(a >= b);
ASSERT_TRUE(b <= c);
ASSERT_TRUE(a < c);
+
+ //negation
+ Float128 pa(1.0),na(-1.0f);
+ ASSERT_TRUE(-pa == na);
+ ASSERT_TRUE(-(-pa)== -na);
+}
+
+TEST(LlvmLibcFloat128Test, BinaryOperators) {
+ Float128 a(1.0f), b(1.0f), c(2.0f), d(3.0);
+ ASSERT_TRUE((a + b) == c);
+ ASSERT_TRUE((a - b) == Float128(0.0));
+ ASSERT_TRUE((c * d) == Float128(6.0));
+ ASSERT_TRUE((Float128(6.0) / d) == Float128(2.0));
}
>From bff51268699b8463ccdef566ce21e2a5f306cad1 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 11 Jun 2026 20:57:53 +0530
Subject: [PATCH 28/44] testing float128 add_sub addition
---
libc/src/__support/FPUtil/generic/add_sub.h | 10 +++++++++-
libc/test/src/math/smoke/float128_test.cpp | 18 +++++++++---------
2 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/libc/src/__support/FPUtil/generic/add_sub.h b/libc/src/__support/FPUtil/generic/add_sub.h
index cf662d051c162..0a2208f43cf05 100644
--- a/libc/src/__support/FPUtil/generic/add_sub.h
+++ b/libc/src/__support/FPUtil/generic/add_sub.h
@@ -116,7 +116,15 @@ add_or_sub(InType x, InType y) {
if constexpr (IsSub)
out_y_bits.set_sign(out_y_bits.sign().negate());
return out_y_bits.get_val();
- } else {
+ }
+ else if constexpr (cpp::is_same_v<InType, Float128> &&
+ cpp::is_same_v<OutType, Float128>) {
+ OutFPBits out_y_bits(y);
+ if constexpr (IsSub)
+ out_y_bits.set_sign(out_y_bits.sign().negate());
+ return out_y_bits.get_val();
+ }
+ else {
#ifdef LIBC_USE_CONSTEXPR
InType tmp = y;
diff --git a/libc/test/src/math/smoke/float128_test.cpp b/libc/test/src/math/smoke/float128_test.cpp
index 1a3a9a6c45726..41323bccb3467 100644
--- a/libc/test/src/math/smoke/float128_test.cpp
+++ b/libc/test/src/math/smoke/float128_test.cpp
@@ -22,7 +22,7 @@ TEST(LlvmLibcFloat128Test, UnaryOperators) {
// comparison operators
ASSERT_TRUE(a == b);
- ASSERT_TRUE(a == Float128(1.0));
+ // ASSERT_TRUE(a == Float128(1.0));
ASSERT_TRUE(a != c);
ASSERT_TRUE(b != c);
ASSERT_TRUE(c > b);
@@ -30,16 +30,16 @@ TEST(LlvmLibcFloat128Test, UnaryOperators) {
ASSERT_TRUE(b <= c);
ASSERT_TRUE(a < c);
- //negation
- Float128 pa(1.0),na(-1.0f);
- ASSERT_TRUE(-pa == na);
- ASSERT_TRUE(-(-pa)== -na);
+ // //negation
+ // Float128 pa(1.0),na(-1.0f);
+ // ASSERT_TRUE(-pa == na);
+ // ASSERT_TRUE(-(-pa)== -na);
}
TEST(LlvmLibcFloat128Test, BinaryOperators) {
- Float128 a(1.0f), b(1.0f), c(2.0f), d(3.0);
+ Float128 a(1.0f), b(1.0f), c(2.0f), d(3.0f);
ASSERT_TRUE((a + b) == c);
- ASSERT_TRUE((a - b) == Float128(0.0));
- ASSERT_TRUE((c * d) == Float128(6.0));
- ASSERT_TRUE((Float128(6.0) / d) == Float128(2.0));
+ ASSERT_TRUE((a - b) == Float128(0.0f));
+ ASSERT_TRUE((c * d) == Float128(6.0f));
+ ASSERT_TRUE((Float128(6.0f) / d) == Float128(2.0f));
}
>From 29b5195e6b52ca8dc41f31e59698da6d85378aca Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 11 Jun 2026 20:59:53 +0530
Subject: [PATCH 29/44] testing intype = outType
---
libc/src/__support/FPUtil/generic/add_sub.h | 10 +---------
1 file changed, 1 insertion(+), 9 deletions(-)
diff --git a/libc/src/__support/FPUtil/generic/add_sub.h b/libc/src/__support/FPUtil/generic/add_sub.h
index 0a2208f43cf05..729b4afc9afca 100644
--- a/libc/src/__support/FPUtil/generic/add_sub.h
+++ b/libc/src/__support/FPUtil/generic/add_sub.h
@@ -110,15 +110,7 @@ add_or_sub(InType x, InType y) {
#endif // LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
}
- if constexpr (cpp::is_same_v<InType, bfloat16> &&
- cpp::is_same_v<OutType, bfloat16>) {
- OutFPBits out_y_bits(y);
- if constexpr (IsSub)
- out_y_bits.set_sign(out_y_bits.sign().negate());
- return out_y_bits.get_val();
- }
- else if constexpr (cpp::is_same_v<InType, Float128> &&
- cpp::is_same_v<OutType, Float128>) {
+ if constexpr (cpp::is_same_v<InType, OutType>) {
OutFPBits out_y_bits(y);
if constexpr (IsSub)
out_y_bits.set_sign(out_y_bits.sign().negate());
>From de4740cf3b2e1476437ec546f4c2d27f4d1a9acd Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 11 Jun 2026 21:08:11 +0530
Subject: [PATCH 30/44] removed checker for LIBC_USE_CONSTEXPR
---
libc/src/__support/FPUtil/generic/add_sub.h | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/libc/src/__support/FPUtil/generic/add_sub.h b/libc/src/__support/FPUtil/generic/add_sub.h
index 729b4afc9afca..bdec242f4a591 100644
--- a/libc/src/__support/FPUtil/generic/add_sub.h
+++ b/libc/src/__support/FPUtil/generic/add_sub.h
@@ -115,17 +115,11 @@ add_or_sub(InType x, InType y) {
if constexpr (IsSub)
out_y_bits.set_sign(out_y_bits.sign().negate());
return out_y_bits.get_val();
- }
- else {
-
-#ifdef LIBC_USE_CONSTEXPR
- InType tmp = y;
-#else
+ } else {
// volatile prevents Clang from converting tmp to OutType and then
// immediately back to InType before negating it, resulting in double
// rounding.
volatile InType tmp = y;
-#endif // LIBC_USE_CONSTEXPR
if constexpr (IsSub)
tmp = -tmp;
return cast<OutType>(tmp);
>From 77e636c4d09986d35308a46b90aec38ea319a041 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 18 Jun 2026 18:39:29 +0530
Subject: [PATCH 31/44] int conversion + tests
temporary tests
clang-format
int conversion testing
---
libc/src/__support/FPUtil/bfloat16.h | 10 ++--
libc/src/__support/FPUtil/float128.h | 57 ++++++++++++++++------
libc/test/src/math/smoke/float128_test.cpp | 36 +++++++++++++-
3 files changed, 82 insertions(+), 21 deletions(-)
diff --git a/libc/src/__support/FPUtil/bfloat16.h b/libc/src/__support/FPUtil/bfloat16.h
index 8a3f3c9894aad..d7889843ac736 100644
--- a/libc/src/__support/FPUtil/bfloat16.h
+++ b/libc/src/__support/FPUtil/bfloat16.h
@@ -136,12 +136,10 @@ struct BFloat16 {
} // namespace LIBC_NAMESPACE_DECL
// <--To be removed------------------------------------>
-static_assert(
- LIBC_NAMESPACE::cpp::is_trivially_constructible<
- LIBC_NAMESPACE::fputil::BFloat16>::value);
-static_assert(
- LIBC_NAMESPACE::cpp::is_trivially_copyable<
- LIBC_NAMESPACE::fputil::BFloat16>::value);
+static_assert(LIBC_NAMESPACE::cpp::is_trivially_constructible<
+ LIBC_NAMESPACE::fputil::BFloat16>::value);
+static_assert(LIBC_NAMESPACE::cpp::is_trivially_copyable<
+ LIBC_NAMESPACE::fputil::BFloat16>::value);
// ----------------------------------------------------
#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_BFLOAT16_H
diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index 663d54a8de01e..642e348220a29 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -9,18 +9,18 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H
#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/FPUtil/cast.h"
#include "src/__support/FPUtil/comparison_operations.h"
-#include "src/__support/macros/attributes.h"
-#include "src/__support/macros/config.h"
-#include "src/__support/uint128.h"
-#include <stdint.h>
-#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/dyadic_float.h"
#include "src/__support/FPUtil/generic/add_sub.h"
#include "src/__support/FPUtil/generic/div.h"
#include "src/__support/FPUtil/generic/mul.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/uint128.h"
+#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
namespace fputil {
@@ -34,7 +34,7 @@ struct Float128 {
LIBC_INLINE constexpr Float128 &operator=(const Float128 &) = default;
LIBC_INLINE constexpr Float128 &operator=(Float128 &&) = default;
- // Floating point type and integer type
+ // Floating point type and integer type
template <typename T>
LIBC_INLINE constexpr explicit Float128(T value)
: bits(static_cast<UInt128>(0U)) {
@@ -67,7 +67,21 @@ struct Float128 {
LIBC_INLINE LIBC_CONSTEXPR_DEFAULT operator T() const {
return fputil::cast<T>(*this);
}
-// TODO: Integer conversion
+
+ // Integer conversion (Incomplete + not verified with tests)
+ template <typename T, cpp::enable_if_t<cpp::is_integral_v<T>, int> = 0>
+ LIBC_INLINE constexpr explicit operator T() const {
+ fputil::FPBits<Float128> x_bits(*this);
+ if (x_bits.is_zero())
+ return static_cast<T>(0);
+
+ fputil::DyadicFloat<fputil::FPBits<Float128>::STORAGE_LEN> xd(
+ x_bits.sign(),
+ x_bits.get_explicit_exponent() - fputil::FPBits<Float128>::FRACTION_LEN,
+ x_bits.get_explicit_mantissa());
+ return static_cast<T>(xd.as_mantissa_type_rounded());
+ }
+
// unary
LIBC_INLINE LIBC_BIT_CAST_CONSTEXPR Float128 operator-() const {
fputil::FPBits<Float128> result(*this);
@@ -75,7 +89,7 @@ struct Float128 {
return result.get_val();
}
// operator overloads
- LIBC_INLINE constexpr Float128 operator+(const Float128 &other) const {
+ LIBC_INLINE constexpr Float128 operator+(const Float128 &other) const {
return fputil::generic::add<Float128>(*this, other);
}
@@ -114,17 +128,32 @@ struct Float128 {
LIBC_INLINE constexpr bool operator>=(const Float128 &other) const {
return fputil::greater_than_or_equals(*this, other);
}
+
+ LIBC_INLINE constexpr Float128 &operator*=(const Float128 &other) {
+ *this = *this * other;
+ return *this;
+ }
+ LIBC_INLINE constexpr Float128 &operator+=(const Float128 &other) {
+ *this = *this + other;
+ return *this;
+ }
+ LIBC_INLINE constexpr Float128 &operator-=(const Float128 &other) {
+ *this = *this - other;
+ return *this;
+ }
+ LIBC_INLINE constexpr Float128 &operator/=(const Float128 &other) {
+ *this = *this / other;
+ return *this;
+ }
};
} // namespace fputil
} // namespace LIBC_NAMESPACE_DECL
// <--To be removed------------------------------------>
-static_assert(
- LIBC_NAMESPACE::cpp::is_trivially_constructible<
- LIBC_NAMESPACE::fputil::Float128>::value);
-static_assert(
- LIBC_NAMESPACE::cpp::is_trivially_copyable<
- LIBC_NAMESPACE::fputil::Float128>::value);
+static_assert(LIBC_NAMESPACE::cpp::is_trivially_constructible<
+ LIBC_NAMESPACE::fputil::Float128>::value);
+static_assert(LIBC_NAMESPACE::cpp::is_trivially_copyable<
+ LIBC_NAMESPACE::fputil::Float128>::value);
// ----------------------------------------------------
#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H
diff --git a/libc/test/src/math/smoke/float128_test.cpp b/libc/test/src/math/smoke/float128_test.cpp
index 41323bccb3467..0e4126edd91be 100644
--- a/libc/test/src/math/smoke/float128_test.cpp
+++ b/libc/test/src/math/smoke/float128_test.cpp
@@ -30,7 +30,7 @@ TEST(LlvmLibcFloat128Test, UnaryOperators) {
ASSERT_TRUE(b <= c);
ASSERT_TRUE(a < c);
- // //negation
+ // //negation
// Float128 pa(1.0),na(-1.0f);
// ASSERT_TRUE(-pa == na);
// ASSERT_TRUE(-(-pa)== -na);
@@ -43,3 +43,37 @@ TEST(LlvmLibcFloat128Test, BinaryOperators) {
ASSERT_TRUE((c * d) == Float128(6.0f));
ASSERT_TRUE((Float128(6.0f) / d) == Float128(2.0f));
}
+
+TEST(LlvmLibcFloat128Test, Negation) {
+ Float128 pa(1.0f), na(-1.0f);
+ ASSERT_TRUE(-pa == na);
+ ASSERT_TRUE(-(-pa) == pa);
+ ASSERT_TRUE(-na == pa);
+}
+
+TEST(LlvmLibcFloat128Test, CompoundAssignment) {
+ Float128 a(1.0f), b(2.0f), c(3.0f), d(4.0f);
+
+ a += Float128(2.0f);
+ ASSERT_TRUE(a == c);
+
+ b -= Float128(1.0f);
+ ASSERT_TRUE(b == Float128(1.0f));
+
+ c *= Float128(2.0f);
+ ASSERT_TRUE(c == Float128(6.0f));
+
+ d /= Float128(2.0f);
+ ASSERT_TRUE(d == Float128(2.0f));
+}
+
+TEST(LlvmLibcFloat128Test, IntegerConversion) {
+ ASSERT_EQ(static_cast<int>(Float128(0.0f)), 0);
+ ASSERT_EQ(static_cast<int>(Float128(1.0f)), 1);
+ ASSERT_EQ(static_cast<int>(Float128(-1.0f)), -1);
+ ASSERT_EQ(static_cast<int>(Float128(42.0f)), 42);
+ ASSERT_EQ(static_cast<int>(Float128(-42.0f)), -42);
+ ASSERT_EQ(static_cast<long long>(Float128(123456789.0)),
+ static_cast<long long>(123456789));
+ ASSERT_EQ(static_cast<unsigned>(Float128(7.0f)), 7U);
+}
>From d4e8ad3473933d330585a0341ec2911434cdd2e8 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 18 Jun 2026 19:41:55 +0530
Subject: [PATCH 32/44] int conversion
---
libc/src/__support/FPUtil/float128.h | 11 +++++------
libc/test/src/math/smoke/float128_test.cpp | 2 +-
2 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index 642e348220a29..8f50df91f2486 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -71,13 +71,12 @@ struct Float128 {
// Integer conversion (Incomplete + not verified with tests)
template <typename T, cpp::enable_if_t<cpp::is_integral_v<T>, int> = 0>
LIBC_INLINE constexpr explicit operator T() const {
- fputil::FPBits<Float128> x_bits(*this);
- if (x_bits.is_zero())
- return static_cast<T>(0);
-
- fputil::DyadicFloat<fputil::FPBits<Float128>::STORAGE_LEN> xd(
+ FPBits<Float128> x_bits(*this);
+ int x_bits_exp = x_bits.get_explicit_exponent() - FPBits<Float128>::FRACTION_LEN;
+ // sign * mantissa * 2(exp-bias)
+ DyadicFloat<FPBits<Float128>::STORAGE_LEN> xd(
x_bits.sign(),
- x_bits.get_explicit_exponent() - fputil::FPBits<Float128>::FRACTION_LEN,
+ x_bits_exp,
x_bits.get_explicit_mantissa());
return static_cast<T>(xd.as_mantissa_type_rounded());
}
diff --git a/libc/test/src/math/smoke/float128_test.cpp b/libc/test/src/math/smoke/float128_test.cpp
index 0e4126edd91be..0ebcce3248c1f 100644
--- a/libc/test/src/math/smoke/float128_test.cpp
+++ b/libc/test/src/math/smoke/float128_test.cpp
@@ -18,7 +18,7 @@ TEST(LlvmLibcFloat128Test, DefaultConstructor) {
}
TEST(LlvmLibcFloat128Test, UnaryOperators) {
- Float128 a(1.0f), b(1.0f), c(2.0f);
+ Float128 a(1.0), b(1.0f), c(2.0f);
// comparison operators
ASSERT_TRUE(a == b);
>From b1d1db9664e8ecde4f6351988a2974f87b91da89 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Fri, 19 Jun 2026 03:22:56 +0530
Subject: [PATCH 33/44] cleanup and tests
fix for test fails
clang format
cleanup for test
---
libc/src/__support/FPUtil/bfloat16.h | 7 --
libc/src/__support/FPUtil/float128.h | 12 +--
libc/src/__support/FPUtil/generic/add_sub.h | 6 ++
libc/test/src/__support/FPUtil/CMakeLists.txt | 11 +++
.../src/__support/FPUtil/float128_test.cpp | 91 +++++++++++++++++++
libc/test/src/math/smoke/CMakeLists.txt | 10 --
libc/test/src/math/smoke/float128_test.cpp | 79 ----------------
7 files changed, 110 insertions(+), 106 deletions(-)
create mode 100644 libc/test/src/__support/FPUtil/float128_test.cpp
delete mode 100644 libc/test/src/math/smoke/float128_test.cpp
diff --git a/libc/src/__support/FPUtil/bfloat16.h b/libc/src/__support/FPUtil/bfloat16.h
index d7889843ac736..ce4e3160a0963 100644
--- a/libc/src/__support/FPUtil/bfloat16.h
+++ b/libc/src/__support/FPUtil/bfloat16.h
@@ -135,11 +135,4 @@ struct BFloat16 {
} // namespace fputil
} // namespace LIBC_NAMESPACE_DECL
-// <--To be removed------------------------------------>
-static_assert(LIBC_NAMESPACE::cpp::is_trivially_constructible<
- LIBC_NAMESPACE::fputil::BFloat16>::value);
-static_assert(LIBC_NAMESPACE::cpp::is_trivially_copyable<
- LIBC_NAMESPACE::fputil::BFloat16>::value);
-// ----------------------------------------------------
-
#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_BFLOAT16_H
diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index 8f50df91f2486..9fdd47bb48597 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -50,8 +50,7 @@ struct Float128 {
}
}
- fputil::DyadicFloat<cpp::numeric_limits<cpp::make_unsigned_t<T>>::digits>
- xd(sign, 0, value);
+ fputil::DyadicFloat<FPBits<Float128>::STORAGE_LEN> xd(sign, 0, value);
bits = xd.template as<Float128, /*ShouldSignalExceptions=*/true>().bits;
} else if constexpr (cpp::is_convertible_v<T, Float128>) {
@@ -68,7 +67,6 @@ struct Float128 {
return fputil::cast<T>(*this);
}
- // Integer conversion (Incomplete + not verified with tests)
template <typename T, cpp::enable_if_t<cpp::is_integral_v<T>, int> = 0>
LIBC_INLINE constexpr explicit operator T() const {
FPBits<Float128> x_bits(*this);
@@ -78,7 +76,7 @@ struct Float128 {
x_bits.sign(),
x_bits_exp,
x_bits.get_explicit_mantissa());
- return static_cast<T>(xd.as_mantissa_type_rounded());
+ return static_cast<T>(xd.as_mantissa_type());
}
// unary
@@ -149,10 +147,4 @@ struct Float128 {
} // namespace fputil
} // namespace LIBC_NAMESPACE_DECL
-// <--To be removed------------------------------------>
-static_assert(LIBC_NAMESPACE::cpp::is_trivially_constructible<
- LIBC_NAMESPACE::fputil::Float128>::value);
-static_assert(LIBC_NAMESPACE::cpp::is_trivially_copyable<
- LIBC_NAMESPACE::fputil::Float128>::value);
-// ----------------------------------------------------
#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H
diff --git a/libc/src/__support/FPUtil/generic/add_sub.h b/libc/src/__support/FPUtil/generic/add_sub.h
index bdec242f4a591..71e50daa9a996 100644
--- a/libc/src/__support/FPUtil/generic/add_sub.h
+++ b/libc/src/__support/FPUtil/generic/add_sub.h
@@ -116,10 +116,16 @@ add_or_sub(InType x, InType y) {
out_y_bits.set_sign(out_y_bits.sign().negate());
return out_y_bits.get_val();
} else {
+
+#ifdef LIBC_USE_CONSTEXPR
+ InType tmp = y;
+#else
// volatile prevents Clang from converting tmp to OutType and then
// immediately back to InType before negating it, resulting in double
// rounding.
volatile InType tmp = y;
+#endif // LIBC_USE_CONSTEXPR
+
if constexpr (IsSub)
tmp = -tmp;
return cast<OutType>(tmp);
diff --git a/libc/test/src/__support/FPUtil/CMakeLists.txt b/libc/test/src/__support/FPUtil/CMakeLists.txt
index 81db4ccae44c6..e38c9bcdc9fcd 100644
--- a/libc/test/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/test/src/__support/FPUtil/CMakeLists.txt
@@ -39,6 +39,17 @@ add_fp_unittest(
libc.src.__support.FPUtil.rounding_mode
)
+add_libc_test(
+ float128_test
+ SUITE
+ libc-fputil-tests
+ SRCS
+ float128_test.cpp
+ DEPENDS
+ libc.src.__support.FPUtil.float128
+ libc.src.__support.uint128
+)
+
# TODO: Temporally disable bfloat16 test until MPCommon target is updated
# https://github.com/llvm/llvm-project/pull/149678
if(LLVM_LIBC_FULL_BUILD)
diff --git a/libc/test/src/__support/FPUtil/float128_test.cpp b/libc/test/src/__support/FPUtil/float128_test.cpp
new file mode 100644
index 0000000000000..31d852c0c9bab
--- /dev/null
+++ b/libc/test/src/__support/FPUtil/float128_test.cpp
@@ -0,0 +1,91 @@
+//===-- Unittests for Float128 emulated type -----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/FPUtil/float128.h"
+#include "test/UnitTest/Test.h"
+
+using LIBC_NAMESPACE::Sign;
+using LIBC_NAMESPACE::fputil::Float128;
+
+TEST(LlvmLibcFloat128Test, Operators) {
+ Float128 a(1.0f), b(1.0f), c(2.0f), d(3.0f), pa(1.0f), na(-1.0f);
+
+ // comparison operators
+ ASSERT_TRUE(a == b);
+ ASSERT_TRUE(a == Float128(1.0));
+ ASSERT_TRUE(a != c);
+ ASSERT_TRUE(b != c);
+ ASSERT_TRUE(c > b);
+ ASSERT_TRUE(a >= b);
+ ASSERT_TRUE(b <= c);
+ ASSERT_TRUE(a < c);
+
+ // Unary operators
+ ASSERT_TRUE(-pa == na);
+ ASSERT_TRUE(-(-pa) == pa);
+
+ // Binary operators
+ ASSERT_TRUE((a + b) == c);
+ ASSERT_TRUE((a - b) == Float128(0.0f));
+ ASSERT_TRUE((c * d) == Float128(6.0f));
+ ASSERT_TRUE((Float128(6.0f) / d) == Float128(2.0f));
+
+ // Compound assignment operators
+ a += Float128(1.0f);
+ ASSERT_TRUE(a == c);
+ b -= Float128(1.0f);
+ ASSERT_TRUE(b == Float128(0.0f));
+ c *= Float128(2.0f);
+ ASSERT_TRUE(c == Float128(4.0f));
+ d /= Float128(3.0f);
+ ASSERT_TRUE(d == Float128(1.0f));
+}
+
+TEST(LlvmLibcFloat128Test, SpecialValues) {
+ using FPBits = LIBC_NAMESPACE::fputil::FPBits<Float128>;
+
+ Float128 zero = FPBits::zero(Sign::POS).get_val();
+ Float128 neg_zero = FPBits::zero(Sign::NEG).get_val();
+ Float128 inf = FPBits::inf(Sign::POS).get_val();
+ Float128 neg_inf = FPBits::inf(Sign::NEG).get_val();
+ Float128 nan = FPBits::quiet_nan().get_val();
+
+ // checking operators with special values
+ ASSERT_TRUE(zero == neg_zero); // +0.0 == -0.0 is true
+ ASSERT_TRUE(zero == Float128(0.0f));
+ ASSERT_TRUE(inf == inf);
+ ASSERT_TRUE(-inf == neg_inf);
+ ASSERT_TRUE((inf + Float128(1.0f)) == inf);
+ ASSERT_TRUE(inf + inf == inf);
+ ASSERT_TRUE(nan != nan);
+ ASSERT_TRUE(!(nan == nan));
+ ASSERT_TRUE(nan != zero);
+}
+
+TEST(LlvmLibcFloat128Test, IntegerConversion) {
+ // Float128 to Integer conversion test
+ ASSERT_EQ(static_cast<int>(Float128(0.0f)), 0);
+ ASSERT_EQ(static_cast<int>(Float128(1.0f)), 1);
+ ASSERT_EQ(static_cast<int>(Float128(-1.0)), -1);
+ ASSERT_EQ(static_cast<long long>(Float128(1000000000.0)),
+ static_cast<long long>(1000000000));
+ ASSERT_EQ(static_cast<unsigned>(Float128(7.0f)), 7U);
+ ASSERT_EQ(static_cast<int>(Float128(-1.5)), -1);
+ ASSERT_EQ(static_cast<int>(Float128(-1.9)), -1);
+ ASSERT_EQ(static_cast<int>(Float128(1.9f)), 1);
+}
+
+TEST(LlvmLibcFloat128Test, FromIntegralTypes) {
+ // Integer to float128 conversion test
+ ASSERT_TRUE(Float128(42) == Float128(42.0f));
+ ASSERT_TRUE(Float128(-42) == Float128(-42.0f));
+ ASSERT_TRUE(Float128(0) == Float128(0.0f));
+ ASSERT_TRUE(Float128(7U) == Float128(7.0f));
+ ASSERT_TRUE(Float128(-7LL) == Float128(-7.0));
+ ASSERT_TRUE(Float128(123456789LL) == Float128(123456789.0));
+}
\ No newline at end of file
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 3081a62552c49..e4e2fb11438d4 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -1,16 +1,6 @@
add_custom_target(libc-math-smoke-tests)
add_dependencies(libc-math-unittests libc-math-smoke-tests)
-add_libc_unittest(
- float128_test
- SUITE
- libc-math-smoke-tests
- SRCS
- float128_test.cpp
- DEPENDS
- libc.src.__support.FPUtil.float128
-)
-
add_fp_unittest(
cosf_test
SUITE
diff --git a/libc/test/src/math/smoke/float128_test.cpp b/libc/test/src/math/smoke/float128_test.cpp
deleted file mode 100644
index 0ebcce3248c1f..0000000000000
--- a/libc/test/src/math/smoke/float128_test.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-//===-- Unittests for Float128 emulated type -----------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "src/__support/FPUtil/float128.h"
-#include "src/__support/uint128.h"
-#include "test/UnitTest/Test.h"
-
-using LIBC_NAMESPACE::fputil::Float128;
-
-TEST(LlvmLibcFloat128Test, DefaultConstructor) {
- Float128 x;
- (void)x;
-}
-
-TEST(LlvmLibcFloat128Test, UnaryOperators) {
- Float128 a(1.0), b(1.0f), c(2.0f);
-
- // comparison operators
- ASSERT_TRUE(a == b);
- // ASSERT_TRUE(a == Float128(1.0));
- ASSERT_TRUE(a != c);
- ASSERT_TRUE(b != c);
- ASSERT_TRUE(c > b);
- ASSERT_TRUE(a >= b);
- ASSERT_TRUE(b <= c);
- ASSERT_TRUE(a < c);
-
- // //negation
- // Float128 pa(1.0),na(-1.0f);
- // ASSERT_TRUE(-pa == na);
- // ASSERT_TRUE(-(-pa)== -na);
-}
-
-TEST(LlvmLibcFloat128Test, BinaryOperators) {
- Float128 a(1.0f), b(1.0f), c(2.0f), d(3.0f);
- ASSERT_TRUE((a + b) == c);
- ASSERT_TRUE((a - b) == Float128(0.0f));
- ASSERT_TRUE((c * d) == Float128(6.0f));
- ASSERT_TRUE((Float128(6.0f) / d) == Float128(2.0f));
-}
-
-TEST(LlvmLibcFloat128Test, Negation) {
- Float128 pa(1.0f), na(-1.0f);
- ASSERT_TRUE(-pa == na);
- ASSERT_TRUE(-(-pa) == pa);
- ASSERT_TRUE(-na == pa);
-}
-
-TEST(LlvmLibcFloat128Test, CompoundAssignment) {
- Float128 a(1.0f), b(2.0f), c(3.0f), d(4.0f);
-
- a += Float128(2.0f);
- ASSERT_TRUE(a == c);
-
- b -= Float128(1.0f);
- ASSERT_TRUE(b == Float128(1.0f));
-
- c *= Float128(2.0f);
- ASSERT_TRUE(c == Float128(6.0f));
-
- d /= Float128(2.0f);
- ASSERT_TRUE(d == Float128(2.0f));
-}
-
-TEST(LlvmLibcFloat128Test, IntegerConversion) {
- ASSERT_EQ(static_cast<int>(Float128(0.0f)), 0);
- ASSERT_EQ(static_cast<int>(Float128(1.0f)), 1);
- ASSERT_EQ(static_cast<int>(Float128(-1.0f)), -1);
- ASSERT_EQ(static_cast<int>(Float128(42.0f)), 42);
- ASSERT_EQ(static_cast<int>(Float128(-42.0f)), -42);
- ASSERT_EQ(static_cast<long long>(Float128(123456789.0)),
- static_cast<long long>(123456789));
- ASSERT_EQ(static_cast<unsigned>(Float128(7.0f)), 7U);
-}
>From d58e1274331e916fd92d70bcf717fb1209adba26 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Wed, 24 Jun 2026 20:54:08 +0530
Subject: [PATCH 34/44] use IEEE754_Binary128 as the container
---
libc/src/__support/FPUtil/FPBits.h | 13 ++-----------
libc/test/src/__support/FPUtil/float128_test.cpp | 2 +-
2 files changed, 3 insertions(+), 12 deletions(-)
diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index 5b7461a44cff5..83219b7573f46 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -37,8 +37,7 @@ enum class FPType {
IEEE754_Binary64,
IEEE754_Binary128,
X86_Binary80,
- BFloat16,
- Float128
+ BFloat16
};
// The classes hierarchy is as follows:
@@ -147,14 +146,6 @@ template <> struct FPLayout<FPType::BFloat16> {
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = SIG_LEN;
};
-template <> struct FPLayout<FPType::Float128> {
- using StorageType = UInt128;
- LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
- LIBC_INLINE_VAR static constexpr int EXP_LEN = 15;
- LIBC_INLINE_VAR static constexpr int SIG_LEN = 112;
- LIBC_INLINE_VAR static constexpr int FRACTION_LEN = SIG_LEN;
-};
-
// FPStorage derives useful constants from the FPLayout above.
template <FPType fp_type> struct FPStorage : public FPLayout<fp_type> {
using UP = FPLayout<fp_type>;
@@ -823,7 +814,7 @@ template <typename T> LIBC_INLINE static constexpr FPType get_fp_type() {
else if constexpr (cpp::is_same_v<UnqualT, bfloat16>)
return FPType::BFloat16;
else if constexpr (cpp::is_same_v<UnqualT, Float128>)
- return FPType::Float128;
+ return FPType::IEEE754_Binary128;
else
static_assert(cpp::always_false<UnqualT>, "Unsupported type");
}
diff --git a/libc/test/src/__support/FPUtil/float128_test.cpp b/libc/test/src/__support/FPUtil/float128_test.cpp
index 31d852c0c9bab..de37226034ddd 100644
--- a/libc/test/src/__support/FPUtil/float128_test.cpp
+++ b/libc/test/src/__support/FPUtil/float128_test.cpp
@@ -88,4 +88,4 @@ TEST(LlvmLibcFloat128Test, FromIntegralTypes) {
ASSERT_TRUE(Float128(7U) == Float128(7.0f));
ASSERT_TRUE(Float128(-7LL) == Float128(-7.0));
ASSERT_TRUE(Float128(123456789LL) == Float128(123456789.0));
-}
\ No newline at end of file
+}
>From 3fe0ffb2ce47d7b0b858e50aa7707e953d06682f Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Wed, 24 Jun 2026 21:13:01 +0530
Subject: [PATCH 35/44] clang-format
---
libc/src/__support/FPUtil/float128.h | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index 9fdd47bb48597..50a0f93cbd297 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -70,12 +70,11 @@ struct Float128 {
template <typename T, cpp::enable_if_t<cpp::is_integral_v<T>, int> = 0>
LIBC_INLINE constexpr explicit operator T() const {
FPBits<Float128> x_bits(*this);
- int x_bits_exp = x_bits.get_explicit_exponent() - FPBits<Float128>::FRACTION_LEN;
+ int x_bits_exp =
+ x_bits.get_explicit_exponent() - FPBits<Float128>::FRACTION_LEN;
// sign * mantissa * 2(exp-bias)
DyadicFloat<FPBits<Float128>::STORAGE_LEN> xd(
- x_bits.sign(),
- x_bits_exp,
- x_bits.get_explicit_mantissa());
+ x_bits.sign(), x_bits_exp, x_bits.get_explicit_mantissa());
return static_cast<T>(xd.as_mantissa_type());
}
>From dbff9d63942b95263358a1927c0ce22c24083f43 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Wed, 24 Jun 2026 21:18:43 +0530
Subject: [PATCH 36/44] 1:1 dependency
---
libc/src/__support/FPUtil/CMakeLists.txt | 11 ++++++++---
libc/src/__support/FPUtil/float128.h | 1 -
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt
index c49d873b026e2..8b6ac8027b52d 100644
--- a/libc/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/src/__support/FPUtil/CMakeLists.txt
@@ -299,12 +299,17 @@ add_header_library(
HDRS
float128.h
DEPENDS
- libc.src.__support.CPP.bit
+ .cast
+ .comparison_operations
+ .dyadic_float
+ libc.hdr.stdint_proxy
+ libc.src.__support.CPP.type_traits
+ libc.src.__support.FPUtil.generic.add_sub
+ libc.src.__support.FPUtil.generic.div
+ libc.src.__support.FPUtil.generic.mul
libc.src.__support.macros.attributes
libc.src.__support.macros.config
libc.src.__support.uint128
- libc.src.__support.CPP.type_traits
- .comparison_operations
)
add_subdirectory(generic)
diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index 50a0f93cbd297..cbb113567dc05 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -20,7 +20,6 @@
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
#include "src/__support/uint128.h"
-#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
namespace fputil {
>From cc932fdaa5e49248714849a0aa2e1aa0c8819058 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 25 Jun 2026 21:02:20 +0530
Subject: [PATCH 37/44] test: bigInt
---
libc/src/__support/FPUtil/float128.h | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index cbb113567dc05..025c8d2170256 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -141,7 +141,12 @@ struct Float128 {
return *this;
}
};
-
+static_assert(
+ LIBC_NAMESPACE::cpp::is_trivially_constructible<
+ LIBC_NAMESPACE::fputil::Float128>::value);
+static_assert(
+ LIBC_NAMESPACE::cpp::is_trivially_copyable<
+ LIBC_NAMESPACE::fputil::Float128>::value);
} // namespace fputil
} // namespace LIBC_NAMESPACE_DECL
>From 93e04f4352821bedfe2bc291511db88cd19fcc08 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 25 Jun 2026 21:19:04 +0530
Subject: [PATCH 38/44] force win
---
libc/src/__support/macros/properties/types.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/src/__support/macros/properties/types.h b/libc/src/__support/macros/properties/types.h
index 7b861640c785d..43a8c43b596b1 100644
--- a/libc/src/__support/macros/properties/types.h
+++ b/libc/src/__support/macros/properties/types.h
@@ -42,7 +42,7 @@
#endif // UINT64_MAX
// int128 / uint128 support
-#if defined(__SIZEOF_INT128__) && !defined(LIBC_TARGET_OS_IS_WINDOWS)
+#if defined(__SIZEOF_INT128__)
#define LIBC_TYPES_HAS_INT128
#endif // defined(__SIZEOF_INT128__)
>From fc52ea9b1cd4c5a1ff43f12a85df4471a0ca8f5c Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Thu, 25 Jun 2026 21:45:31 +0530
Subject: [PATCH 39/44] test: big_int Trivially const
---
libc/src/__support/macros/properties/types.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/src/__support/macros/properties/types.h b/libc/src/__support/macros/properties/types.h
index 43a8c43b596b1..7b861640c785d 100644
--- a/libc/src/__support/macros/properties/types.h
+++ b/libc/src/__support/macros/properties/types.h
@@ -42,7 +42,7 @@
#endif // UINT64_MAX
// int128 / uint128 support
-#if defined(__SIZEOF_INT128__)
+#if defined(__SIZEOF_INT128__) && !defined(LIBC_TARGET_OS_IS_WINDOWS)
#define LIBC_TYPES_HAS_INT128
#endif // defined(__SIZEOF_INT128__)
>From 0d421fbff5a859b9b54c3ee6a99ad055e31346f1 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 28 Jun 2026 02:13:29 +0530
Subject: [PATCH 40/44] revert last change
---
libc/src/__support/big_int.h | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/libc/src/__support/big_int.h b/libc/src/__support/big_int.h
index 55768b6a8333e..5c1cd3e118d6a 100644
--- a/libc/src/__support/big_int.h
+++ b/libc/src/__support/big_int.h
@@ -358,7 +358,7 @@ struct BigInt {
LIBC_INLINE_VAR static constexpr size_t WORD_COUNT = Bits / WORD_SIZE;
- cpp::array<WordType, WORD_COUNT> val; // zero initialized.
+ cpp::array<WordType, WORD_COUNT> val{}; // zero initialized.
LIBC_INLINE constexpr BigInt() = default;
@@ -1392,11 +1392,6 @@ first_trailing_one(T value) {
return value == 0 ? 0 : cpp::countr_zero(value) + 1;
}
-static_assert(LIBC_NAMESPACE::cpp::is_trivially_constructible<
- LIBC_NAMESPACE::BigInt<128, false>>::value);
-static_assert(LIBC_NAMESPACE::cpp::is_trivially_copyable<
- LIBC_NAMESPACE::BigInt<128, false>>::value);
-
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SRC___SUPPORT_BIG_INT_H
>From 9b2fb90c7f40ccf6f98dff26a9dff55b412e6b65 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 28 Jun 2026 23:15:11 +0530
Subject: [PATCH 41/44] test: braces
---
libc/src/__support/big_int.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/src/__support/big_int.h b/libc/src/__support/big_int.h
index 5c1cd3e118d6a..70834dace768c 100644
--- a/libc/src/__support/big_int.h
+++ b/libc/src/__support/big_int.h
@@ -358,7 +358,7 @@ struct BigInt {
LIBC_INLINE_VAR static constexpr size_t WORD_COUNT = Bits / WORD_SIZE;
- cpp::array<WordType, WORD_COUNT> val{}; // zero initialized.
+ cpp::array<WordType, WORD_COUNT> val; // zero initialized.
LIBC_INLINE constexpr BigInt() = default;
>From d549db663be12481fe4f342ac145bc84fee8bc24 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sun, 28 Jun 2026 23:48:34 +0530
Subject: [PATCH 42/44] clang-format
---
libc/src/__support/FPUtil/float128.h | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index 025c8d2170256..661dfe808f8b2 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -141,12 +141,12 @@ struct Float128 {
return *this;
}
};
-static_assert(
- LIBC_NAMESPACE::cpp::is_trivially_constructible<
- LIBC_NAMESPACE::fputil::Float128>::value);
-static_assert(
- LIBC_NAMESPACE::cpp::is_trivially_copyable<
- LIBC_NAMESPACE::fputil::Float128>::value);
+
+static_assert(LIBC_NAMESPACE::cpp::is_trivially_constructible<
+ LIBC_NAMESPACE::fputil::Float128>::value);
+static_assert(LIBC_NAMESPACE::cpp::is_trivially_copyable<
+ LIBC_NAMESPACE::fputil::Float128>::value);
+
} // namespace fputil
} // namespace LIBC_NAMESPACE_DECL
>From 2b11151a8946b7d21ddb1392e9a839c3a69e1ce8 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Mon, 29 Jun 2026 16:00:33 +0530
Subject: [PATCH 43/44] test: emulated float128 with ceilf128
---
libc/shared/math/ceilf128.h | 9 +++------
libc/src/__support/math/ceilf128.h | 11 ++++-------
libc/src/math/ceilf128.h | 5 ++++-
libc/src/math/generic/ceilf128.cpp | 5 ++++-
libc/test/src/math/ceilf128_test.cpp | 5 ++++-
5 files changed, 19 insertions(+), 16 deletions(-)
diff --git a/libc/shared/math/ceilf128.h b/libc/shared/math/ceilf128.h
index b9e6655393e14..25611636e2233 100644
--- a/libc/shared/math/ceilf128.h
+++ b/libc/shared/math/ceilf128.h
@@ -9,12 +9,11 @@
#ifndef LLVM_LIBC_SHARED_MATH_CEILF128_H
#define LLVM_LIBC_SHARED_MATH_CEILF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/ceilf128.h"
+#include "src/__support/FPUtil/float128.h"
+
+using LIBC_NAMESPACE::fputil::Float128;
namespace LIBC_NAMESPACE_DECL {
namespace shared {
@@ -24,6 +23,4 @@ using math::ceilf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_CEILF128_H
diff --git a/libc/src/__support/math/ceilf128.h b/libc/src/__support/math/ceilf128.h
index 8877594d58d68..f12fc6a11a07c 100644
--- a/libc/src/__support/math/ceilf128.h
+++ b/libc/src/__support/math/ceilf128.h
@@ -9,21 +9,18 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_CEILF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_CEILF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "src/__support/FPUtil/NearestIntegerOperations.h"
#include "src/__support/macros/config.h"
+#include "src/__support/FPUtil/float128.h"
+
+using LIBC_NAMESPACE::fputil::Float128;
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE constexpr float128 ceilf128(float128 x) { return fputil::ceil(x); }
+LIBC_INLINE constexpr Float128 ceilf128(Float128 x) { return fputil::ceil(x); }
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_CEILF128_H
diff --git a/libc/src/math/ceilf128.h b/libc/src/math/ceilf128.h
index 211b8131a9559..40de768feb299 100644
--- a/libc/src/math/ceilf128.h
+++ b/libc/src/math/ceilf128.h
@@ -11,10 +11,13 @@
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/types.h"
+#include "src/__support/FPUtil/float128.h"
+
+using LIBC_NAMESPACE::fputil::Float128;
namespace LIBC_NAMESPACE_DECL {
-float128 ceilf128(float128 x);
+Float128 ceilf128(Float128 x);
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/ceilf128.cpp b/libc/src/math/generic/ceilf128.cpp
index fd9c206612207..e359ef9cb18b7 100644
--- a/libc/src/math/generic/ceilf128.cpp
+++ b/libc/src/math/generic/ceilf128.cpp
@@ -8,10 +8,13 @@
#include "src/math/ceilf128.h"
#include "src/__support/math/ceilf128.h"
+#include "src/__support/FPUtil/float128.h"
+
+using LIBC_NAMESPACE::fputil::Float128;
namespace LIBC_NAMESPACE_DECL {
-LLVM_LIBC_FUNCTION(float128, ceilf128, (float128 x)) {
+LLVM_LIBC_FUNCTION(Float128, ceilf128, (Float128 x)) {
return math::ceilf128(x);
}
diff --git a/libc/test/src/math/ceilf128_test.cpp b/libc/test/src/math/ceilf128_test.cpp
index f0da8258f79bc..e01221f4ac6cd 100644
--- a/libc/test/src/math/ceilf128_test.cpp
+++ b/libc/test/src/math/ceilf128_test.cpp
@@ -9,5 +9,8 @@
#include "CeilTest.h"
#include "src/math/ceilf128.h"
+#include "src/__support/FPUtil/float128.h"
-LIST_CEIL_TESTS(float128, LIBC_NAMESPACE::ceilf128)
+using LIBC_NAMESPACE::fputil::Float128;
+
+LIST_CEIL_TESTS(Float128, LIBC_NAMESPACE::ceilf128)
>From 0de258c84b7c2df8af3b9cb6f76ba858ed9fcb34 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Mon, 29 Jun 2026 16:15:56 +0530
Subject: [PATCH 44/44] test: float128
---
libc/src/__support/math/ceilf128.h | 3 ---
libc/test/shared/shared_math_test.cpp | 11 ++++++++++-
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/libc/src/__support/math/ceilf128.h b/libc/src/__support/math/ceilf128.h
index f12fc6a11a07c..0361251b664a9 100644
--- a/libc/src/__support/math/ceilf128.h
+++ b/libc/src/__support/math/ceilf128.h
@@ -11,9 +11,6 @@
#include "src/__support/FPUtil/NearestIntegerOperations.h"
#include "src/__support/macros/config.h"
-#include "src/__support/FPUtil/float128.h"
-
-using LIBC_NAMESPACE::fputil::Float128;
namespace LIBC_NAMESPACE_DECL {
namespace math {
diff --git a/libc/test/shared/shared_math_test.cpp b/libc/test/shared/shared_math_test.cpp
index 8ae2aac3d51ed..165591594f45e 100644
--- a/libc/test/shared/shared_math_test.cpp
+++ b/libc/test/shared/shared_math_test.cpp
@@ -575,6 +575,16 @@ TEST(LlvmLibcSharedMathTest, AllLongDouble) {
#endif // LIBC_TYPES_LONG_DOUBLE_IS_DOUBLE_DOUBLE
+// Emulated float128
+// TODO: style
+#include "src/__support/FPUtil/float128.h"
+
+using LIBC_NAMESPACE::fputil::Float128;
+
+TEST(LlvmLibcSharedMathTest, AllEmuFloat128){
+ EXPECT_FP_EQ(Float128(0.0), LIBC_NAMESPACE::shared::ceilf128(Float128(0.0)));
+}
+
#ifdef LIBC_TYPES_HAS_FLOAT128
TEST(LlvmLibcSharedMathTest, AllFloat128) {
@@ -620,7 +630,6 @@ TEST(LlvmLibcSharedMathTest, AllFloat128) {
float128(0.0), float128(0.0)));
EXPECT_FP_EQ(bfloat16(2.0), LIBC_NAMESPACE::shared::bf16divf128(
float128(4.0), float128(2.0)));
- EXPECT_FP_EQ(float128(0.0), LIBC_NAMESPACE::shared::ceilf128(float128(0.0)));
EXPECT_FP_EQ(float128(0.0), LIBC_NAMESPACE::shared::copysignf128(
float128(0.0), float128(0.0)));
EXPECT_FP_EQ(float128(0.0),
More information about the libc-commits
mailing list