Skip to content
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

[libc] Refactor BigInt #86137

Merged
merged 19 commits into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions libc/fuzzing/CMakeLists.txt
@@ -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
@@ -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
@@ -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
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