Skip to content

Commit

Permalink
[libc] Provide LIBC_TYPES_HAS_INT128 (llvm#84149)
Browse files Browse the repository at this point in the history
Umbrella bug llvm#83182
  • Loading branch information
gchatelet authored Mar 8, 2024
1 parent 01e5d46 commit 23c397c
Show file tree
Hide file tree
Showing 22 changed files with 72 additions and 36 deletions.
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__

// '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

0 comments on commit 23c397c

Please sign in to comment.