Skip to content
Draft
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
15 changes: 9 additions & 6 deletions lib/Support/BigIntSupport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1741,10 +1741,6 @@ multiply(MutableBigIntRef dst, ImmutableBigIntRef lhs, ImmutableBigIntRef rhs) {

namespace {
namespace div_rem {
static uint32_t getResultSize(ImmutableBigIntRef lhs, ImmutableBigIntRef rhs) {
return std::max(lhs.numDigits, rhs.numDigits) + 1;
}

static OperationStatus compute(
MutableBigIntRef quoc,
MutableBigIntRef rem,
Expand Down Expand Up @@ -1868,7 +1864,14 @@ static OperationStatus compute(
} // namespace

uint32_t divideResultSize(ImmutableBigIntRef lhs, ImmutableBigIntRef rhs) {
return div_rem::getResultSize(lhs, rhs);
if (isNegative(lhs) && compare(rhs, -1) == 0) {
// In this (and only this) case, we can end up with more digits than we started with
// Examples: -(2n**63n)/-1n, -(2n**127n)/-1n
// We avoid this in general case as it makes division much slower
return std::max(lhs.numDigits, rhs.numDigits) + 1;
}

return std::max(lhs.numDigits, rhs.numDigits);
}

OperationStatus
Expand All @@ -1879,7 +1882,7 @@ divide(MutableBigIntRef dst, ImmutableBigIntRef lhs, ImmutableBigIntRef rhs) {
}

uint32_t remainderResultSize(ImmutableBigIntRef lhs, ImmutableBigIntRef rhs) {
return div_rem::getResultSize(lhs, rhs);
return divideResultSize(lhs, rhs); // We currently expect them to be equivalent in div_rem::compute()
}

OperationStatus remainder(
Expand Down