Skip to content

[libc] Provide LIBC_TYPES_HAS_INT128 #84149

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions libc/src/__support/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ add_header_library(
libc.src.__support.CPP.bit
libc.src.__support.CPP.type_traits
libc.src.__support.macros.optimization
libc.src.__support.macros.properties.types
)

add_header_library(
Expand All @@ -213,6 +214,7 @@ add_header_library(
UInt128.h
DEPENDS
.uint
libc.src.__support.macros.properties.types
)

add_header_library(
Expand Down
1 change: 1 addition & 0 deletions libc/src/__support/CPP/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ add_header_library(
DEPENDS
.type_traits
libc.include.llvm-libc-macros.limits_macros
libc.src.__support.macros.properties.types
)

add_header_library(
Expand Down
5 changes: 3 additions & 2 deletions libc/src/__support/CPP/limits.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
#include "include/llvm-libc-macros/limits-macros.h" // CHAR_BIT
#include "src/__support/CPP/type_traits/is_integral.h"
#include "src/__support/CPP/type_traits/is_signed.h"
#include "src/__support/macros/attributes.h" // LIBC_INLINE
#include "src/__support/macros/attributes.h" // LIBC_INLINE
#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128

namespace LIBC_NAMESPACE {
namespace cpp {
Expand Down Expand Up @@ -76,7 +77,7 @@ template <>
struct numeric_limits<unsigned char>
: public internal::integer_impl<unsigned char, 0, UCHAR_MAX> {};

#ifdef __SIZEOF_INT128__
#ifdef LIBC_TYPES_HAS_INT128
// On platform where UInt128 resolves to __uint128_t, this specialization
// provides the limits of UInt128.
template <>
Expand Down
3 changes: 2 additions & 1 deletion libc/src/__support/CPP/type_traits/is_integral.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "src/__support/CPP/type_traits/is_same.h"
#include "src/__support/CPP/type_traits/remove_cv.h"
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128

namespace LIBC_NAMESPACE::cpp {

Expand All @@ -25,7 +26,7 @@ template <typename T> struct is_integral {
public:
LIBC_INLINE_VAR static constexpr bool value = __is_unqualified_any_of<
T,
#ifdef __SIZEOF_INT128__
#ifdef LIBC_TYPES_HAS_INT128
__int128_t, __uint128_t,
#endif
char, signed char, unsigned char, short, unsigned short, int,
Expand Down
3 changes: 2 additions & 1 deletion libc/src/__support/CPP/type_traits/make_signed.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#define LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_MAKE_SIGNED_H

#include "src/__support/CPP/type_traits/type_identity.h"
#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128

namespace LIBC_NAMESPACE::cpp {

Expand All @@ -26,7 +27,7 @@ template <> struct make_signed<unsigned int> : type_identity<int> {};
template <> struct make_signed<unsigned long> : type_identity<long> {};
template <>
struct make_signed<unsigned long long> : type_identity<long long> {};
#ifdef __SIZEOF_INT128__
#ifdef LIBC_TYPES_HAS_INT128
template <> struct make_signed<__int128_t> : type_identity<__int128_t> {};
template <> struct make_signed<__uint128_t> : type_identity<__int128_t> {};
#endif
Expand Down
3 changes: 2 additions & 1 deletion libc/src/__support/CPP/type_traits/make_unsigned.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#define LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_MAKE_UNSIGNED_H

#include "src/__support/CPP/type_traits/type_identity.h"
#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128

namespace LIBC_NAMESPACE::cpp {

Expand All @@ -31,7 +32,7 @@ template <>
struct make_unsigned<unsigned long> : type_identity<unsigned long> {};
template <>
struct make_unsigned<unsigned long long> : type_identity<unsigned long long> {};
#ifdef __SIZEOF_INT128__
#ifdef LIBC_TYPES_HAS_INT128
template <> struct make_unsigned<__int128_t> : type_identity<__uint128_t> {};
template <> struct make_unsigned<__uint128_t> : type_identity<__uint128_t> {};
#endif
Expand Down
23 changes: 12 additions & 11 deletions libc/src/__support/UInt.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@
#include "src/__support/CPP/limits.h"
#include "src/__support/CPP/optional.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/macros/attributes.h" // LIBC_INLINE
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
#include "src/__support/math_extras.h" // SumCarry, DiffBorrow
#include "src/__support/macros/attributes.h" // LIBC_INLINE
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128
#include "src/__support/math_extras.h" // SumCarry, DiffBorrow
#include "src/__support/number_pair.h"

#include <stddef.h> // For size_t
Expand All @@ -30,9 +31,9 @@ template <typename T> struct half_width;
template <> struct half_width<uint64_t> : cpp::type_identity<uint32_t> {};
template <> struct half_width<uint32_t> : cpp::type_identity<uint16_t> {};
template <> struct half_width<uint16_t> : cpp::type_identity<uint8_t> {};
#ifdef __SIZEOF_INT128__
#ifdef LIBC_TYPES_HAS_INT128
template <> struct half_width<__uint128_t> : cpp::type_identity<uint64_t> {};
#endif // __SIZEOF_INT128__
#endif // LIBC_TYPES_HAS_INT128

template <typename T> using half_width_t = typename half_width<T>::type;

Expand Down Expand Up @@ -69,7 +70,7 @@ LIBC_INLINE constexpr NumberPair<uint32_t> full_mul<uint32_t>(uint32_t a,
return result;
}

#ifdef __SIZEOF_INT128__
#ifdef LIBC_TYPES_HAS_INT128
template <>
LIBC_INLINE constexpr NumberPair<uint64_t> full_mul<uint64_t>(uint64_t a,
uint64_t b) {
Expand All @@ -79,7 +80,7 @@ LIBC_INLINE constexpr NumberPair<uint64_t> full_mul<uint64_t>(uint64_t a,
result.hi = uint64_t(prod >> 64);
return result;
}
#endif // __SIZEOF_INT128__
#endif // LIBC_TYPES_HAS_INT128

} // namespace internal

Expand Down Expand Up @@ -682,7 +683,7 @@ struct BigInt {
val[1] = uint32_t(tmp >> 32);
return;
}
#ifdef __SIZEOF_INT128__
#ifdef LIBC_TYPES_HAS_INT128
if constexpr ((Bits == 128) && (WORD_SIZE == 64)) {
// Use builtin 128 bits if available;
if (s >= 128) {
Expand All @@ -696,7 +697,7 @@ struct BigInt {
val[1] = uint64_t(tmp >> 64);
return;
}
#endif // __SIZEOF_INT128__
#endif // LIBC_TYPES_HAS_INT128
if (LIBC_UNLIKELY(s == 0))
return;

Expand Down Expand Up @@ -753,7 +754,7 @@ struct BigInt {
val[1] = uint32_t(tmp >> 32);
return;
}
#ifdef __SIZEOF_INT128__
#ifdef LIBC_TYPES_HAS_INT128
if constexpr ((Bits == 128) && (WORD_SIZE == 64)) {
// Use builtin 128 bits if available;
if (s >= 128) {
Expand All @@ -771,7 +772,7 @@ struct BigInt {
val[1] = uint64_t(tmp >> 64);
return;
}
#endif // __SIZEOF_INT128__
#endif // LIBC_TYPES_HAS_INT128

if (LIBC_UNLIKELY(s == 0))
return;
Expand Down
5 changes: 3 additions & 2 deletions libc/src/__support/UInt128.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@
#define LLVM_LIBC_SRC___SUPPORT_UINT128_H

#include "UInt.h"
#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128

#if defined(__SIZEOF_INT128__)
#ifdef LIBC_TYPES_HAS_INT128
using UInt128 = __uint128_t;
using Int128 = __int128_t;
#else
using UInt128 = LIBC_NAMESPACE::UInt<128>;
using Int128 = LIBC_NAMESPACE::Int<128>;
#endif
#endif // LIBC_TYPES_HAS_INT128

#endif // LLVM_LIBC_SRC___SUPPORT_UINT128_H
7 changes: 7 additions & 0 deletions libc/src/__support/macros/properties/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#include "src/__support/macros/properties/cpu_features.h"
#include "src/__support/macros/properties/os.h"

#include <stdint.h> // __SIZEOF_INT128__
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you include include/llvm-libc-macros/stdint-macros.h instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not in this PR for the same reasons as #83441 (comment)


// 'long double' properties.
#if (LDBL_MANT_DIG == 53)
#define LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64
Expand All @@ -26,6 +28,11 @@
#define LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128
#endif

// int128 / uint128 support
#if defined(__SIZEOF_INT128__)
#define LIBC_TYPES_HAS_INT128
#endif // defined(__SIZEOF_INT128__)

// -- float16 support ---------------------------------------------------------
// TODO: move this logic to "llvm-libc-types/float16.h"
#if defined(LIBC_TARGET_ARCH_IS_X86_64) && defined(LIBC_TARGET_CPU_HAS_SSE2)
Expand Down
1 change: 1 addition & 0 deletions libc/test/UnitTest/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ add_unittest_framework_library(
libc.src.__support.CPP.string_view
libc.src.__support.CPP.type_traits
libc.src.__support.fixed_point.fx_rep
libc.src.__support.macros.properties.types
libc.src.__support.OSUtil.osutil
libc.src.__support.uint
libc.src.__support.uint128
Expand Down
5 changes: 3 additions & 2 deletions libc/test/UnitTest/LibcTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "src/__support/CPP/string_view.h"
#include "src/__support/UInt128.h"
#include "src/__support/fixed_point/fx_rep.h"
#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128
#include "test/UnitTest/TestLogger.h"

#if __STDC_HOSTED__
Expand Down Expand Up @@ -215,11 +216,11 @@ TEST_SPECIALIZATION(bool);

// We cannot just use a single UInt128 specialization as that resolves to only
// one type, UInt<128> or __uint128_t. We want both overloads as we want to
#ifdef __SIZEOF_INT128__
#ifdef LIBC_TYPES_HAS_INT128
// When builtin __uint128_t type is available, include its specialization
// also.
TEST_SPECIALIZATION(__uint128_t);
#endif
#endif // LIBC_TYPES_HAS_INT128

TEST_SPECIALIZATION(LIBC_NAMESPACE::Int<128>);

Expand Down
5 changes: 3 additions & 2 deletions libc/test/UnitTest/TestLogger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "src/__support/OSUtil/io.h" // write_to_stderr
#include "src/__support/UInt.h" // is_big_int
#include "src/__support/UInt128.h"
#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128

#include <stdint.h>

Expand Down Expand Up @@ -72,9 +73,9 @@ template TestLogger &TestLogger::operator<< <unsigned long>(unsigned long);
template TestLogger &
TestLogger::operator<< <unsigned long long>(unsigned long long);

#ifdef __SIZEOF_INT128__
#ifdef LIBC_TYPES_HAS_INT128
template TestLogger &TestLogger::operator<< <__uint128_t>(__uint128_t);
#endif
#endif // LIBC_TYPES_HAS_INT128
template TestLogger &TestLogger::operator<< <UInt<128>>(UInt<128>);
template TestLogger &TestLogger::operator<< <UInt<192>>(UInt<192>);
template TestLogger &TestLogger::operator<< <UInt<256>>(UInt<256>);
Expand Down
6 changes: 4 additions & 2 deletions libc/test/src/__support/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,9 @@ if(NOT LIBC_TARGET_ARCHITECTURE_IS_NVPTX)
SRCS
uint_test.cpp
DEPENDS
libc.src.__support.uint
libc.src.__support.CPP.optional
libc.src.__support.macros.properties.types
libc.src.__support.uint
)
endif()

Expand All @@ -118,8 +119,9 @@ add_libc_test(
SRCS
integer_literals_test.cpp
DEPENDS
libc.src.__support.integer_literals
libc.src.__support.CPP.optional
libc.src.__support.integer_literals
libc.src.__support.macros.properties.types
)

add_libc_test(
Expand Down
2 changes: 2 additions & 0 deletions libc/test/src/__support/CPP/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ add_libc_test(
bit_test.cpp
DEPENDS
libc.src.__support.CPP.bit
libc.src.__support.macros.properties.types
libc.src.__support.uint
)

Expand Down Expand Up @@ -49,6 +50,7 @@ add_libc_test(
limits_test.cpp
DEPENDS
libc.src.__support.CPP.limits
libc.src.__support.macros.properties.types
libc.src.__support.uint
)

Expand Down
9 changes: 5 additions & 4 deletions libc/test/src/__support/CPP/bit_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,24 @@

#include "src/__support/CPP/bit.h"
#include "src/__support/UInt.h"
#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128
#include "test/UnitTest/Test.h"

#include <stdint.h>

namespace LIBC_NAMESPACE::cpp {

using UnsignedTypesNoBigInt = testing::TypeList<
#if defined(__SIZEOF_INT128__)
#if defined(LIBC_TYPES_HAS_INT128)
__uint128_t,
#endif
#endif // LIBC_TYPES_HAS_INT128
unsigned char, unsigned short, unsigned int, unsigned long,
unsigned long long>;

using UnsignedTypes = testing::TypeList<
#if defined(__SIZEOF_INT128__)
#if defined(LIBC_TYPES_HAS_INT128)
__uint128_t,
#endif
#endif // LIBC_TYPES_HAS_INT128
unsigned char, unsigned short, unsigned int, unsigned long,
unsigned long long, UInt<128>>;

Expand Down
5 changes: 3 additions & 2 deletions libc/test/src/__support/CPP/limits_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "src/__support/CPP/limits.h"
#include "src/__support/UInt.h"
#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128
#include "test/UnitTest/Test.h"

namespace LIBC_NAMESPACE {
Expand Down Expand Up @@ -36,9 +37,9 @@ TEST(LlvmLibcLimitsTest, UInt128Limits) {
auto umax64 = LIBC_NAMESPACE::UInt<128>(cpp::numeric_limits<uint64_t>::max());
EXPECT_GT(umax128, umax64);
ASSERT_EQ(~LIBC_NAMESPACE::UInt<128>(0), umax128);
#ifdef __SIZEOF_INT128__
#ifdef LIBC_TYPES_HAS_INT128
ASSERT_EQ(~__uint128_t(0), cpp::numeric_limits<__uint128_t>::max());
#endif
#endif // LIBC_TYPES_HAS_INT128
}

} // namespace LIBC_NAMESPACE
5 changes: 3 additions & 2 deletions libc/test/src/__support/integer_literals_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//

#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;
Expand Down Expand Up @@ -66,7 +67,7 @@ TEST(LlvmLibcIntegerLiteralTest, u64) {
}

TEST(LlvmLibcIntegerLiteralTest, u128) {
#if defined(__SIZEOF_INT128__)
#ifdef LIBC_TYPES_HAS_INT128
const __uint128_t ZERO = 0;
const __uint128_t U8_MAX = UINT8_MAX;
const __uint128_t U16_MAX = UINT16_MAX;
Expand All @@ -80,7 +81,7 @@ TEST(LlvmLibcIntegerLiteralTest, u128) {
const UInt128 U32_MAX = UINT32_MAX;
const UInt128 U64_MAX = UINT64_MAX;
const UInt128 U128_MAX = (U64_MAX << 64) | U64_MAX;
#endif
#endif // LIBC_TYPES_HAS_INT128
EXPECT_EQ(ZERO, 0_u128);
EXPECT_EQ(U8_MAX, 255_u128);
EXPECT_EQ(U8_MAX, 0xFF_u128);
Expand Down
Loading