Skip to content

Fix library bugs found by the reworked tests - #9

Merged
Auburn merged 9 commits into
masterfrom
test-harness
Oct 13, 2026
Merged

Auburn merged 9 commits into
masterfrom
test-harness

Conversation

@Auburn

@Auburn Auburn commented Oct 10, 2026 •

Copy link
Copy Markdown
Owner

Library fixes found by a reworked test harness (the harness itself will follow separately).

  • MSVC x86 operators: binary operators took lhs by value, and MSVC x86 /O2 didn't copy over-aligned by value arguments, so the result was written into the caller's register.
  • FS::Log: the e * -2.12194440e-4f term used *= instead of +=, making Log (and Pow) up to ~1.6% wrong.
  • AVX/AVX512 !=: used _CMP_NEQ_OQ, which is false when an input is NaN.
  • Min/Max: didn't match std::min/std::max for +-0 and NaN on x86, WASM and ARM (non relaxed).
  • NEON Cast of mask registers: didn't compile with GCC, which has no implicit uint32x4_t conversions.
  • FMA contraction: non relaxed dispatch libraries are now built with -ffp-contract=off. GCC/Clang fused mul + add into FMA (AVX512F has its own FMA even with -mno-fma), so feature sets gave different results.

The binary operators took lhs by value and modified it in place. MSVC x86
/O2 doesn't copy over-aligned by value arguments, so the result was written
into the caller's register, e.g. Select( m, a * b, a ) read back a * b.
Take lhs by const& and copy into a local instead.
The e * -2.12194440e-4f correction multiplied the polynomial instead of
being added to it, making FS::Log (and FS::Pow, which uses it) up to ~1.6%
wrong, e.g. Log( 1.5 ) gave 0.41211 instead of 0.40547.
_CMP_NEQ_OQ is false when either input is NaN. Use the unordered
_CMP_NEQ_UQ, matching SSE cmpneqps, the other platforms and C++ !=.
x86 minps/maxps return their 2nd operand for equal (+-0) or NaN inputs, and
WASM min/max and ARM vminq/vmaxq propagate NaN, so feature sets disagreed
with each other and with the scalar std::min/std::max. Non relaxed Min/Max
now all give b < a ? b : a (and a < b ? b : a): x86 swaps the operands, WASM
uses pmin/pmax and ARM selects with vbslq. Relaxed keeps the native ops.
GCC has no implicit conversion between uint32x4_t and float32x4_t or
int32x4_t, so casting a mask register didn't compile. Reinterpret every
native type through uint32x4_t, picked by element type since with the MSVC
ARM64 ABI every NEON vector type is the same __n128.
GCC and Clang fused mul + add into FMA, and -mno-fma isn't enough because
AVX512F has its own FMA instructions, so non relaxed results differed
between feature sets. clang-cl needs the /clang: form.
@Auburn Auburn changed the title Rework test harness Fix library bugs found by the reworked tests Oct 13, 2026
@Auburn
Auburn merged commit 1c34420 into master Oct 13, 2026
8 checks passed
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