mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-12 02:13:04 +08:00
`x % c` for a constant power of two c computes `x - trunc(x / c) * c`. On x86-64 without SSE4.1, trunc is itself an integer round trip, so a division, a multiplication, the round trip and a sign fix sit on the dividend's dependency chain. Loops that feed the remainder back, such as `s = (s + x) % 65536`, ran up to twice as slow as with the integer remainder they used before. Where truncation is a round trip, dividends below 2^62 now take integer paths: - A proven integer dividend takes the i64 remainder. - A computed dividend (`+`, `-` or `*`) takes the i64 remainder when it is an integer. Otherwise, below 2c it is x when |x| < c, behind a predicted branch, and x - copysign(c, x) when not, which is exact. Larger fractions take the path below. - Any other dividend computes (trunc(x) srem c) + (x - trunc(x)) without a branch on whether x is an integer. Huge, infinite and NaN dividends, divisors above 2^52 and targets with a rounding instruction keep the double sequence. No path calls fmod, whose cost grows with the quotient. On a Linux x86-64 sandbox (median ms, main -> this change): an accumulator by 65536 2667 -> 1343, a phase accumulator by 1 2210 -> 432, a fractional generator by 1024 1449 -> 491, an LCG by 2^31 1561 -> 1016, random integers and fractions 593 -> 451. Statically proven operands and other divisors are unchanged. Corpus 5776 covers the bounds of each path, mixed streams at one remainder site, and computed dividends around c and 2c of both signs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>