[libc] [llvm] Revert "[libc] Remove UB specializations of type traits for `BigInt`" (PR #84297)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 7 02:07:20 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libc
Author: Guillaume Chatelet (gchatelet)
<details>
<summary>Changes</summary>
Reverts llvm/llvm-project#<!-- -->84035
Several bots are failing:
- https://lab.llvm.org/buildbot/#/builders/223/builds/37522
- https://lab.llvm.org/buildbot/#/builders/162/builds/51978
- https://lab.llvm.org/buildbot/#/builders/163/builds/52560
- https://lab.llvm.org/buildbot/#/builders/250/builds/19619
---
Patch is 29.90 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/84297.diff
12 Files Affected:
- (modified) libc/src/__support/CMakeLists.txt (-1)
- (modified) libc/src/__support/CPP/bit.h (+43-69)
- (modified) libc/src/__support/UInt.h (+57-135)
- (modified) libc/src/__support/float_to_string.h (+1-1)
- (modified) libc/src/__support/integer_to_string.h (+3-16)
- (modified) libc/test/UnitTest/CMakeLists.txt (-1)
- (modified) libc/test/UnitTest/LibcTest.cpp (+5-5)
- (modified) libc/test/UnitTest/LibcTest.h (-1)
- (modified) libc/test/UnitTest/TestLogger.cpp (+3-5)
- (modified) libc/test/src/__support/CPP/bit_test.cpp (+13-36)
- (modified) utils/bazel/llvm-project-overlay/libc/BUILD.bazel (-1)
- (modified) utils/bazel/llvm-project-overlay/libc/test/UnitTest/BUILD.bazel (-1)
``````````diff
diff --git a/libc/src/__support/CMakeLists.txt b/libc/src/__support/CMakeLists.txt
index 17c04aa57e6fd6..1a4b3e9a2145c0 100644
--- a/libc/src/__support/CMakeLists.txt
+++ b/libc/src/__support/CMakeLists.txt
@@ -95,7 +95,6 @@ add_header_library(
HDRS
integer_to_string.h
DEPENDS
- .uint
libc.src.__support.common
libc.src.__support.CPP.algorithm
libc.src.__support.CPP.limits
diff --git a/libc/src/__support/CPP/bit.h b/libc/src/__support/CPP/bit.h
index bc2f595845a95f..7d11e7d5c497e0 100644
--- a/libc/src/__support/CPP/bit.h
+++ b/libc/src/__support/CPP/bit.h
@@ -27,14 +27,13 @@ namespace LIBC_NAMESPACE::cpp {
// This implementation of bit_cast requires trivially-constructible To, to avoid
// UB in the implementation.
-template <typename To, typename From>
-LIBC_INLINE constexpr cpp::enable_if_t<
- (sizeof(To) == sizeof(From)) &&
- cpp::is_trivially_constructible<To>::value &&
- cpp::is_trivially_copyable<To>::value &&
- cpp::is_trivially_copyable<From>::value,
- To>
-bit_cast(const From &from) {
+template <
+ typename To, typename From,
+ typename = cpp::enable_if_t<sizeof(To) == sizeof(From) &&
+ cpp::is_trivially_constructible<To>::value &&
+ cpp::is_trivially_copyable<To>::value &&
+ cpp::is_trivially_copyable<From>::value>>
+LIBC_INLINE constexpr To bit_cast(const From &from) {
MSAN_UNPOISON(&from, sizeof(From));
#if LIBC_HAS_BUILTIN(__builtin_bit_cast)
return __builtin_bit_cast(To, from);
@@ -52,10 +51,8 @@ bit_cast(const From &from) {
#endif // LIBC_HAS_BUILTIN(__builtin_bit_cast)
}
-template <typename T>
-[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>,
- bool>
-has_single_bit(T value) {
+template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
+[[nodiscard]] LIBC_INLINE constexpr bool has_single_bit(T value) {
return (value != 0) && ((value & (value - 1)) == 0);
}
@@ -73,9 +70,8 @@ has_single_bit(T value) {
/// Only unsigned integral types are allowed.
///
/// Returns cpp::numeric_limits<T>::digits on an input of 0.
-template <typename T>
-[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
-countr_zero(T value) {
+template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
+[[nodiscard]] LIBC_INLINE constexpr int countr_zero(T value) {
if (!value)
return cpp::numeric_limits<T>::digits;
if (value & 0x1)
@@ -107,9 +103,8 @@ ADD_SPECIALIZATION(countr_zero, unsigned long long, __builtin_ctzll)
/// Only unsigned integral types are allowed.
///
/// Returns cpp::numeric_limits<T>::digits on an input of 0.
-template <typename T>
-[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
-countl_zero(T value) {
+template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
+[[nodiscard]] LIBC_INLINE constexpr int countl_zero(T value) {
if (!value)
return cpp::numeric_limits<T>::digits;
// Bisection method.
@@ -140,9 +135,8 @@ ADD_SPECIALIZATION(countl_zero, unsigned long long, __builtin_clzll)
/// Only unsigned integral types are allowed.
///
/// Returns cpp::numeric_limits<T>::digits on an input of all ones.
-template <typename T>
-[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
-countl_one(T value) {
+template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
+[[nodiscard]] LIBC_INLINE constexpr int countl_one(T value) {
return cpp::countl_zero<T>(~value);
}
@@ -153,9 +147,8 @@ countl_one(T value) {
/// Only unsigned integral types are allowed.
///
/// Returns cpp::numeric_limits<T>::digits on an input of all ones.
-template <typename T>
-[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
-countr_one(T value) {
+template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
+[[nodiscard]] LIBC_INLINE constexpr int countr_one(T value) {
return cpp::countr_zero<T>(~value);
}
@@ -163,9 +156,8 @@ countr_one(T value) {
/// Returns 0 otherwise.
///
/// Ex. bit_width(5) == 3.
-template <typename T>
-[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
-bit_width(T value) {
+template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
+[[nodiscard]] LIBC_INLINE constexpr int bit_width(T value) {
return cpp::numeric_limits<T>::digits - cpp::countl_zero(value);
}
@@ -173,9 +165,8 @@ bit_width(T value) {
/// nonzero. Returns 0 otherwise.
///
/// Ex. bit_floor(5) == 4.
-template <typename T>
-[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T>
-bit_floor(T value) {
+template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
+[[nodiscard]] LIBC_INLINE constexpr T bit_floor(T value) {
if (!value)
return 0;
return T(1) << (cpp::bit_width(value) - 1);
@@ -188,9 +179,8 @@ bit_floor(T value) {
///
/// The return value is undefined if the input is larger than the largest power
/// of two representable in T.
-template <typename T>
-[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T>
-bit_ceil(T value) {
+template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
+[[nodiscard]] LIBC_INLINE constexpr T bit_ceil(T value) {
if (value < 2)
return 1;
return T(1) << cpp::bit_width<T>(value - 1u);
@@ -200,31 +190,28 @@ bit_ceil(T value) {
// from https://blog.regehr.org/archives/1063.
// Forward-declare rotr so that rotl can use it.
-template <typename T>
-[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T>
-rotr(T value, int rotate);
+template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
+[[nodiscard]] LIBC_INLINE constexpr T rotr(T value, int rotate);
-template <typename T>
-[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T>
-rotl(T value, int rotate) {
+template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
+[[nodiscard]] LIBC_INLINE constexpr T rotl(T value, int rotate) {
constexpr unsigned N = cpp::numeric_limits<T>::digits;
rotate = rotate % N;
if (!rotate)
return value;
if (rotate < 0)
- return cpp::rotr<T>(value, -rotate);
+ return cpp::rotr(value, -rotate);
return (value << rotate) | (value >> (N - rotate));
}
-template <typename T>
-[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T>
-rotr(T value, int rotate) {
+template <typename T, typename>
+[[nodiscard]] LIBC_INLINE constexpr T rotr(T value, int rotate) {
constexpr unsigned N = cpp::numeric_limits<T>::digits;
rotate = rotate % N;
if (!rotate)
return value;
if (rotate < 0)
- return cpp::rotl<T>(value, -rotate);
+ return cpp::rotl(value, -rotate);
return (value >> rotate) | (value << (N - rotate));
}
@@ -239,44 +226,33 @@ LIBC_INLINE constexpr To bit_or_static_cast(const From &from) {
}
}
-// TODO: remove from 'bit.h' as it is not a standard function.
-template <typename T>
-[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
-first_leading_zero(T value) {
+template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
+[[nodiscard]] LIBC_INLINE constexpr int first_leading_zero(T value) {
return value == cpp::numeric_limits<T>::max() ? 0 : countl_one(value) + 1;
}
-// TODO: remove from 'bit.h' as it is not a standard function.
-template <typename T>
-[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
-first_leading_one(T value) {
+template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
+[[nodiscard]] LIBC_INLINE constexpr int first_leading_one(T value) {
return first_leading_zero(static_cast<T>(~value));
}
-// TODO: remove from 'bit.h' as it is not a standard function.
-template <typename T>
-[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
-first_trailing_zero(T value) {
+template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
+[[nodiscard]] LIBC_INLINE constexpr int first_trailing_zero(T value) {
return value == cpp::numeric_limits<T>::max()
? 0
: countr_zero(static_cast<T>(~value)) + 1;
}
-// TODO: remove from 'bit.h' as it is not a standard function.
-template <typename T>
-[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
-first_trailing_one(T value) {
+template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
+[[nodiscard]] LIBC_INLINE constexpr int first_trailing_one(T value) {
return value == cpp::numeric_limits<T>::max() ? 0 : countr_zero(value) + 1;
}
/// Count number of 1's aka population count or hamming weight.
///
/// Only unsigned integral types are allowed.
-// TODO: rename as 'popcount' to follow the standard
-// https://en.cppreference.com/w/cpp/numeric/popcount
-template <typename T>
-[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
-count_ones(T value) {
+template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
+[[nodiscard]] LIBC_INLINE constexpr int count_ones(T value) {
int count = 0;
for (int i = 0; i != cpp::numeric_limits<T>::digits; ++i)
if ((value >> i) & 0x1)
@@ -296,10 +272,8 @@ ADD_SPECIALIZATION(unsigned long long, __builtin_popcountll)
// TODO: 128b specializations?
#undef ADD_SPECIALIZATION
-// TODO: remove from 'bit.h' as it is not a standard function.
-template <typename T>
-[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
-count_zeros(T value) {
+template <typename T, typename = cpp::enable_if_t<cpp::is_unsigned_v<T>>>
+[[nodiscard]] LIBC_INLINE constexpr int count_zeros(T value) {
return count_ones<T>(static_cast<T>(~value));
}
diff --git a/libc/src/__support/UInt.h b/libc/src/__support/UInt.h
index b3d8f00b9a01a5..5973e6fab1d7d5 100644
--- a/libc/src/__support/UInt.h
+++ b/libc/src/__support/UInt.h
@@ -43,9 +43,6 @@ struct BigInt {
static_assert(is_integral_v<WordType> && is_unsigned_v<WordType>,
"WordType must be unsigned integer.");
- using word_type = WordType;
- LIBC_INLINE_VAR static constexpr bool SIGNED = Signed;
- LIBC_INLINE_VAR static constexpr size_t BITS = Bits;
LIBC_INLINE_VAR
static constexpr size_t WORD_SIZE = sizeof(WordType) * CHAR_BIT;
@@ -53,10 +50,6 @@ struct BigInt {
"Number of bits in BigInt should be a multiple of WORD_SIZE.");
LIBC_INLINE_VAR static constexpr size_t WORD_COUNT = Bits / WORD_SIZE;
-
- using unsigned_type = BigInt<BITS, false, word_type>;
- using signed_type = BigInt<BITS, true, word_type>;
-
cpp::array<WordType, WORD_COUNT> val{};
LIBC_INLINE constexpr BigInt() = default;
@@ -586,33 +579,19 @@ struct BigInt {
return *this;
}
- // TODO: remove and use cpp::countl_zero below.
- [[nodiscard]] LIBC_INLINE constexpr int clz() const {
- constexpr int word_digits = cpp::numeric_limits<word_type>::digits;
- int leading_zeroes = 0;
- for (auto i = val.size(); i > 0;) {
- --i;
- const int zeroes = countl_zero(val[i]);
- leading_zeroes += zeroes;
- if (zeroes != word_digits)
+ LIBC_INLINE constexpr uint64_t clz() {
+ uint64_t leading_zeroes = 0;
+ for (size_t i = WORD_COUNT; i > 0; --i) {
+ if (val[i - 1] == 0) {
+ leading_zeroes += WORD_SIZE;
+ } else {
+ leading_zeroes += countl_zero(val[i - 1]);
break;
+ }
}
return leading_zeroes;
}
- // TODO: remove and use cpp::countr_zero below.
- [[nodiscard]] LIBC_INLINE constexpr int ctz() const {
- constexpr int word_digits = cpp::numeric_limits<word_type>::digits;
- int trailing_zeroes = 0;
- for (auto word : val) {
- const int zeroes = countr_zero(word);
- trailing_zeroes += zeroes;
- if (zeroes != word_digits)
- break;
- }
- return trailing_zeroes;
- }
-
LIBC_INLINE constexpr void shift_left(size_t s) {
if constexpr (Bits == WORD_SIZE) {
// Use native types if possible.
@@ -937,121 +916,64 @@ template <> class numeric_limits<Int<128>> {
LIBC_INLINE_VAR static constexpr int digits = 128;
};
-// type traits to determine whether a T is a cpp::BigInt.
-template <typename T> struct is_big_int : cpp::false_type {};
-
+// Provides is_integral of U/Int<128>, U/Int<192>, U/Int<256>.
template <size_t Bits, bool Signed, typename T>
-struct is_big_int<BigInt<Bits, Signed, T>> : cpp::true_type {};
-
-template <class T>
-LIBC_INLINE_VAR constexpr bool is_big_int_v = is_big_int<T>::value;
-
-// Specialization of cpp::bit_cast ('bit.h') from T to BigInt.
-template <typename To, typename From>
-LIBC_INLINE 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;
-}
+struct is_integral<BigInt<Bits, Signed, T>> : cpp::true_type {};
-// Specialization of cpp::bit_cast ('bit.h') from BigInt to T.
-template <typename To, size_t Bits>
-LIBC_INLINE 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::has_single_bit ('bit.h') for BigInt.
-template <typename T>
-[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_big_int_v<T>, bool>
-has_single_bit(T value) {
- int bits = 0;
- for (auto word : value.val) {
- if (word == 0)
- continue;
- bits += count_ones(word);
- if (bits > 1)
- return false;
- }
- return bits == 1;
-}
-
-// Specialization of cpp::countr_zero ('bit.h') for BigInt.
-template <typename T>
-[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_big_int_v<T>, int>
-countr_zero(const T &value) {
- return value.ctz();
-}
+// Provides is_unsigned of UInt<128>, UInt<192>, UInt<256>.
+template <size_t Bits, bool Signed, typename T>
+struct is_unsigned<BigInt<Bits, Signed, T>> : cpp::bool_constant<!Signed> {};
-// Specialization of cpp::countl_zero ('bit.h') for BigInt.
-template <typename T>
-[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_big_int_v<T>, int>
-countl_zero(const T &value) {
- return value.clz();
-}
+template <size_t Bits, bool Signed, typename T>
+struct make_unsigned<BigInt<Bits, Signed, T>>
+ : type_identity<BigInt<Bits, false, T>> {};
-// Specialization of cpp::countl_one ('bit.h') for BigInt.
-template <typename T>
-[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_big_int_v<T>, int>
-countl_one(T value) {
- // TODO : Implement a faster version not involving operator~.
- return cpp::countl_zero<T>(~value);
-}
+template <size_t Bits, bool Signed, typename T>
+struct make_signed<BigInt<Bits, Signed, T>>
+ : type_identity<BigInt<Bits, true, T>> {};
-// Specialization of cpp::countr_one ('bit.h') for BigInt.
-template <typename T>
-[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_big_int_v<T>, int>
-countr_one(T value) {
- // TODO : Implement a faster version not involving operator~.
- return cpp::countr_zero<T>(~value);
-}
+namespace internal {
+template <typename T> struct is_custom_uint : cpp::false_type {};
-// Specialization of cpp::bit_width ('bit.h') for BigInt.
-template <typename T>
-[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_big_int_v<T>, int>
-bit_width(T value) {
- return cpp::numeric_limits<T>::digits - cpp::countl_zero(value);
-}
+template <size_t Bits, bool Signed, typename T>
+struct is_custom_uint<BigInt<Bits, Signed, T>> : cpp::true_type {};
+} // namespace internal
-// Forward-declare rotr so that rotl can use it.
-template <typename T>
-[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_big_int_v<T>, T>
-rotr(T value, int rotate);
-
-// Specialization of cpp::rotl ('bit.h') for BigInt.
-template <typename T>
-[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_big_int_v<T>, T>
-rotl(T value, int rotate) {
- constexpr unsigned N = cpp::numeric_limits<T>::digits;
- rotate = rotate % N;
- if (!rotate)
- return value;
- if (rotate < 0)
- return cpp::rotr<T>(value, -rotate);
- return (value << rotate) | (value >> (N - rotate));
+// bit_cast to UInt
+// Note: The standard scheme for SFINAE selection is to have exactly one
+// function instanciation valid at a time. This is usually done by having a
+// predicate in one function and the negated predicate in the other one.
+// e.g.
+// template<typename = cpp::enable_if_t< is_custom_uint<To>::value == true> ...
+// template<typename = cpp::enable_if_t< is_custom_uint<To>::value == false> ...
+//
+// Unfortunately this would make the default 'cpp::bit_cast' aware of
+// 'is_custom_uint' (or any other customization). To prevent exposing all
+// customizations in the original function, we create a different function with
+// four 'typename's instead of three - otherwise it would be considered as a
+// redeclaration of the same function leading to "error: template parameter
+// redefines default argument".
+template <typename To, typename From,
+ typename = cpp::enable_if_t<sizeof(To) == sizeof(From) &&
+ cpp::is_trivially_copyable<To>::value &&
+ cpp::is_trivially_copyable<From>::value>,
+ typename = cpp::enable_if_t<internal::is_custom_uint<To>::value>>
+LIBC_INLINE constexpr 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::rotr ('bit.h') for BigInt.
-template <typename T>
-[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_big_int_v<T>, T>
-rotr(T value, int rotate) {
- constexpr unsigned N = cpp::numeric_limits<T>::digits;
- rotate = rotate % N;
- if (!rotate)
- return value;
- if (rotate < 0)
- return cpp::rotl<T>(value, -rotate);
- return (value >> rotate) | (value << (N - rotate));
+// bit_cast from UInt
+template <
+ typename To, size_t Bits,
+ typename = 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>>
+LIBC_INLINE constexpr To bit_cast(const UInt<Bits> &from) {
+ return cpp::bit_cast<To>(from.val);
}
} // namespace LIBC_NAMESPACE::cpp
diff --git a/libc/src/__support/float_to_string.h b/libc/src/__support/float_to_string.h
index 27476433a94575..744842ced8d772 100644
--- a/libc/src/__support/float_to_string.h
+++ b/libc/src/__support/float_to_string.h
@@ -713,7 +713,7 @@ template <> class FloatToString<long double> {
float_as_fixed.shift_left(SHIFT_AMOUNT);
// If there are still digits above the decimal point, handle those.
- if (float_as_fixed.clz() < static_cast<int>(EXTRA_INT_WIDTH)) {
+ if (float_as_fixed.clz() < EXTRA_INT_WIDTH) {
cpp::UInt<EXTRA_INT_WIDTH> above_decimal_point =
float_as_fixed >> FLOAT_AS_INT_WIDTH;
diff --git a/libc/src/__support/integer_to_string.h b/libc/src/__support/integer_to_string.h
index a5872dce652036..81ed21ccfca166 100644
--- a/libc/src/__support/integer_to_string.h
+++ b/libc/src/__support/integer_to_string.h
@@ -67,7 +67,6 @@
#include "src/__support/CPP/span.h"
#include "src/__support/CPP/string_view.h"
#include "src/__support/CPP/type_traits.h"
-#include "src/__support/UInt.h" // is_big_int
#include "src/__support/common.h"
namespace LIBC_NAMESPACE {
@@ -150,18 +149,6 @@ template <bool forward> class StringBufferWriterImpl {
using StringBufferWriter = StringBufferWriterImpl<true>;
using BackwardStringBufferWriter = StringBufferWriterImpl<false>;
-template <typename T, class = void> struct IntegerWriterUnsigned {};
-
-template <typename T>
-struct IntegerWriterUnsigned<T, cpp::enable_if_t<cpp::is_integral_v<T>>> {
- using typ...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/84297
More information about the llvm-commits
mailing list