Skip to content

Commit

Permalink
[reland][libc] Refactor BigInt (#87613)
Browse files Browse the repository at this point in the history
This is a reland of #86137 with a fix for platforms / compiler that do
not support trivially constructible int128 types.
  • Loading branch information
gchatelet committed Apr 4, 2024
1 parent cca9115 commit 71c3f5d
Show file tree
Hide file tree
Showing 13 changed files with 1,014 additions and 762 deletions.
1 change: 1 addition & 0 deletions libc/fuzzing/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=fuzzer")
add_custom_target(libc-fuzzer)

add_subdirectory(__support)
# TODO(#85680): Re-enable math fuzzing after headers are sorted out
# add_subdirectory(math)
add_subdirectory(stdlib)
Expand Down
7 changes: 7 additions & 0 deletions libc/fuzzing/__support/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
add_libc_fuzzer(
uint_fuzz
SRCS
uint_fuzz.cpp
DEPENDS
libc.src.__support.uint
)
70 changes: 70 additions & 0 deletions libc/fuzzing/__support/uint_fuzz.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#include "src/__support/CPP/bit.h"
#include "src/__support/UInt.h"
#include "src/string/memory_utils/inline_memcpy.h"

using namespace LIBC_NAMESPACE;

// Helper function when using gdb / lldb to set a breakpoint and inspect values.
template <typename T> void debug_and_trap(const char *msg, T a, T b) {
__builtin_trap();
}

#define DEBUG_AND_TRAP()

#define TEST_BINOP(OP) \
if ((a OP b) != (static_cast<T>(BigInt(a) OP BigInt(b)))) \
debug_and_trap(#OP, a, b);

#define TEST_SHIFTOP(OP) \
if ((a OP b) != (static_cast<T>(BigInt(a) OP b))) \
debug_and_trap(#OP, a, b);

#define TEST_FUNCTION(FUN) \
if (FUN(a) != FUN(BigInt(a))) \
debug_and_trap(#FUN, a, b);

// Test that basic arithmetic operations of BigInt behave like their scalar
// counterparts.
template <typename T, typename BigInt> void run_tests(T a, T b) {
TEST_BINOP(+)
TEST_BINOP(-)
TEST_BINOP(*)
if (b != 0)
TEST_BINOP(/)
if (b >= 0 && b < cpp::numeric_limits<T>::digits) {
TEST_SHIFTOP(<<)
TEST_SHIFTOP(>>)
}
if constexpr (!BigInt::SIGNED) {
TEST_FUNCTION(cpp::has_single_bit)
TEST_FUNCTION(cpp::countr_zero)
TEST_FUNCTION(cpp::countl_zero)
TEST_FUNCTION(cpp::countl_one)
TEST_FUNCTION(cpp::countr_one)
}
}

// Reads a T from libfuzzer data.
template <typename T> T read(const uint8_t *data, size_t &remainder) {
T out = 0;
constexpr size_t T_SIZE = sizeof(T);
const size_t copy_size = remainder < T_SIZE ? remainder : T_SIZE;
inline_memcpy(&out, data, copy_size);
remainder -= copy_size;
return out;
}

template <typename T, typename BigInt>
void run_tests(const uint8_t *data, size_t size) {
const auto a = read<T>(data, size);
const auto b = read<T>(data, size);
run_tests<T, BigInt>(a, b);
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// unsigned
run_tests<uint64_t, BigInt<64, false, uint16_t>>(data, size);
// signed
run_tests<int64_t, BigInt<64, true, uint16_t>>(data, size);
return 0;
}
6 changes: 3 additions & 3 deletions libc/src/__support/FPUtil/dyadic_float.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ template <size_t Bits> struct DyadicFloat {
// significant bit.
LIBC_INLINE constexpr DyadicFloat &normalize() {
if (!mantissa.is_zero()) {
int shift_length = static_cast<int>(mantissa.clz());
int shift_length = cpp::countl_zero(mantissa);
exponent -= shift_length;
mantissa.shift_left(static_cast<size_t>(shift_length));
mantissa <<= static_cast<size_t>(shift_length);
}
return *this;
}
Expand Down Expand Up @@ -233,7 +233,7 @@ LIBC_INLINE constexpr DyadicFloat<Bits> quick_add(DyadicFloat<Bits> a,
result.sign = a.sign;
result.exponent = a.exponent;
result.mantissa = a.mantissa;
if (result.mantissa.add(b.mantissa)) {
if (result.mantissa.add_overflow(b.mantissa)) {
// Mantissa addition overflow.
result.shift_right(1);
result.mantissa.val[DyadicFloat<Bits>::MantissaType::WORD_COUNT - 1] |=
Expand Down

0 comments on commit 71c3f5d

Please sign in to comment.