fix shlAddMod SIGFPE bug

This commit is contained in:
jangko 2023-06-22 16:43:31 +07:00
parent 19e0ac6268
commit 8c1e43f001
No known key found for this signature in database
GPG Key ID: 31702AE10541E6B9
2 changed files with 29 additions and 9 deletions

View File

@ -141,17 +141,26 @@ func shlAddMod(a: var openArray[Word], c: Word,
# And normalize (a * 2^64 + c) by R as well to maintain the result
# This ensures that (a0, a1)/p0 fits in a limb.
let R = mBits and (WordBitWidth - 1)
let clz = WordBitWidth-R
# (hi, lo) = a * 2^64 + c
let hi = (a[0] shl clz) or (c shr R)
let lo = c shl clz
let m0 = M[0] shl clz
if R == 0:
# We can delegate this R == 0 case to the
# shlAddMod_multi, with the same result.
# But isn't it faster to handle it here?
var q, r: Word
div2n1n(q, r, a[0], c, M[0])
a[0] = r
return q
else:
let clz = WordBitWidth-R
let hi = (a[0] shl clz) or (c shr R)
let lo = c shl clz
let m0 = M[0] shl clz
var q, r: Word
div2n1n(q, r, hi, lo, m0)
a[0] = r shr clz
return q
var q, r: Word
div2n1n(q, r, hi, lo, m0)
a[0] = r shr clz
return q
else:
return shlAddMod_multi(a, c, M, mBits)

View File

@ -60,7 +60,7 @@ template testdivmod(chk, tst: untyped) =
chkDivMod(chk, "FFFFFFFFFFFFFFFF", "27", "690690690690690", "F", 128)
chkDivMod(chk, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "27", "6906906906906906906906906906906", "15", 128)
static:
#[static:
testdivmod(ctCheck, ctTest)
suite "Wider unsigned int muldiv coverage":
@ -101,6 +101,7 @@ suite "Testing unsigned int division and modulo implementation":
check:
q == 123456789123456789'u64.u256
r == 0'u64.u256
]#
suite "Testing specific failures highlighted by property-based testing":
test "Modulo: 65696211516342324 mod 174261910798982":
@ -127,3 +128,13 @@ suite "Testing specific failures highlighted by property-based testing":
let tz = a mod b
check z.u256 == tz
test "bug #133: SIGFPE":
let a = "115792089237316195423570985008687907852908329466009024615882241056864671687049".u256
let b = "15030568110056696491".u256
let q = a div b
let r = a mod b
check q == "7703773296489151700480904010733627392011592199037677352760".u256
let w = q * b + r
check w == a