Skip to content

nan boxing: faster NaN detection in __JS_NewFloat64 - #616

Open
j-olivier wants to merge 1 commit into
bellard:masterfrom
j-olivier:feature/improved-nanboxing
Open

j-olivier wants to merge 1 commit into
bellard:masterfrom
j-olivier:feature/improved-nanboxing

Conversation

@j-olivier

Copy link
Copy Markdown

__JS_NewFloat64() canonicalizes NaN with an integer test on the bit pattern. This replaces it with a
floating point comparison:

-    if (js_unlikely((u.u64 & 0x7fffffffffffffff) > 0x7ff0000000000000))
+    if (js_unlikely(d != d))

Generated code:

target before after
x86-64 (gcc -O2) 8 instructions, 2 constants 5 instructions, 1 constant (ucomisd + jp)
arm64 (clang -O2) 9 instructions 7 instructions, branch free (fcmp + csel)

V8 benchmark, 10 interleaved runs each, pinned to two logical processors at high priority (Intel
Cascade Lake, mingw-w64 gcc -O2). NavierStokes improves by 8.2% (median +6.9%), outside the run to
run noise (sd 0.7% to 3.0%); the other benchmarks are within the noise:

before sd after sd change
Richards 1275 0.6% 1279 1.1% +0.3%
DeltaBlue 1152 1.2% 1160 1.2% +0.7%
Crypto 1473 2.3% 1497 1.0% +1.7%
RayTrace 2124 2.1% 2085 3.0% -1.9%
EarleyBoyer 2737 1.7% 2768 0.7% +1.1%
RegExp 518 1.7% 515 2.5% -0.7%
Splay 4302 1.8% 4333 1.2% +0.7%
NavierStokes 2712 3.0% 2933 0.7% +8.2%
Score 1718 1.5% 1739 0.9% +1.2%

Verification:

  • Old and new __JS_NewFloat64() give identical results on 100M values (random bit patterns, all
    sign/exponent classes, all single-bit NaN payloads, sNaN/qNaN, +-0, +-Inf, denormals), with an exact
    round trip through JS_VALUE_GET_FLOAT64() for non-NaN values. Tested on x86-64 (shift 47, gcc
    -O0/-O2/-O3) and 32-bit x86 (shift 32, clang, SSE2 and x87, -O0/-O2).
  • make test and test262 (x86-64): unchanged results.
  • arm64: code generation checked, not run.

d != d is not compatible with -ffast-math / -ffinite-math-only; they are not used by the Makefile
and quickjs.c already relies on IEEE NaN semantics (isnan()).

@j-olivier
j-olivier force-pushed the feature/improved-nanboxing branch from 0f0f42f to d5f3e43 Compare November 10, 2026 16:13
@j-olivier
j-olivier marked this pull request as ready for review November 10, 2026 16:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant