From 0df19fdc32d62fcaba3e9f7a1b289962bc00118d Mon Sep 17 00:00:00 2001 From: Nikita Skovoroda Date: Sat, 29 Nov 2025 02:27:36 +0400 Subject: [PATCH 1/2] perf: do not allocate extra digit in bigint division --- lib/Support/BigIntSupport.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/Support/BigIntSupport.cpp b/lib/Support/BigIntSupport.cpp index d9b0fe35b64..0e7b34a1b92 100644 --- a/lib/Support/BigIntSupport.cpp +++ b/lib/Support/BigIntSupport.cpp @@ -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, @@ -1868,7 +1864,14 @@ static OperationStatus compute( } // namespace uint32_t divideResultSize(ImmutableBigIntRef lhs, ImmutableBigIntRef rhs) { - return div_rem::getResultSize(lhs, rhs); + if (compare(rhs, -1) == 0 && isNegative(lhs)) { + // 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 @@ -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( From cf6cb613eabfcd82a5b9b9f1193c10ffc096d49b Mon Sep 17 00:00:00 2001 From: Nikita Skovoroda Date: Sun, 7 Dec 2025 05:31:48 +0300 Subject: [PATCH 2/2] nit Co-authored-by: Andrew Toth --- lib/Support/BigIntSupport.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Support/BigIntSupport.cpp b/lib/Support/BigIntSupport.cpp index 0e7b34a1b92..2453fd0bdb9 100644 --- a/lib/Support/BigIntSupport.cpp +++ b/lib/Support/BigIntSupport.cpp @@ -1864,7 +1864,7 @@ static OperationStatus compute( } // namespace uint32_t divideResultSize(ImmutableBigIntRef lhs, ImmutableBigIntRef rhs) { - if (compare(rhs, -1) == 0 && isNegative(lhs)) { + 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