From 6ad747dee7c2273efaea9a866bdb4f3e8f73c937 Mon Sep 17 00:00:00 2001 From: huntedbytheirs Date: Sat, 29 Aug 2026 17:07:42 -0400 Subject: [PATCH] test: make the avx512 mirror reproduce the kernel's real expression The scalar AVX-512 mirror built its whitespace mask from ws_tab lookups, so a bug in the kernel's actual predicate - the (x - 9) < 5 unsigned range trick plus newline/space/NBSP compares - would pass the selftest on hosts without AVX-512 and only surface on real hardware. The mirror now computes the mask with the kernel's exact expression, and check_kernel gains an exhaustive 256-byte ramp (forward and reversed) so any divergence from the reference table changes a count. Verified by mutation: shifting the range constant to (x - 8) < 5 makes the selftest fail. --- src/main.c | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/src/main.c b/src/main.c index 5149e26..a5e2082 100644 --- a/src/main.c +++ b/src/main.c @@ -952,8 +952,11 @@ static long long ref_words(const unsigned char *s, size_t n, int *prev_ws) /* * Scalar mirror of the AVX-512 kernel: identical 64-byte chunking and * 64-bit mask arithmetic (bit-63 carry, 64-bit shift/OR, popcnt) for - * hosts that cannot execute the real zmm code. AVX-2 already proves - * the algorithm; this proves the width. + * hosts that cannot execute the real zmm code. It reproduces the + * kernel's exact whitespace expression - newline/space/NBSP equality + * plus the (x - 9) < 5 unsigned range trick - rather than consulting + * ws_tab, so a bug in the kernel's expression is caught here against + * the reference instead of only on real AVX-512 hardware. */ static lw_t count_lw_avx512_mirror(const unsigned char *s, size_t n, int *prev_ws, int need_lines, int need_words) @@ -967,10 +970,13 @@ static lw_t count_lw_avx512_mirror(const unsigned char *s, size_t n, uint64_t nl_mask = 0, ws = 0; for (size_t j = 0; j < 64; j++) { - if (s[i + j] == '\n') - nl_mask |= (uint64_t)1 << j; - if (ws_tab[s[i + j]]) - ws |= (uint64_t)1 << j; + unsigned char c = s[i + j]; + uint64_t bit = (uint64_t)1 << j; + + if (c == '\n') + nl_mask |= bit; + if (c == '\n' || c == ' ' || c == 0xa0 || (uint8_t)(c - 9) < 5) + ws |= bit; } if (need_lines) lines += (long long)__builtin_popcountll(nl_mask); @@ -1065,6 +1071,24 @@ static int check_kernel(const char *name, count_lw_fn fn) } } + /* exhaustive predicate check: every byte value in a 256-byte ramp, + * forward and reversed, so a divergence between the kernel's + * whitespace expression and the reference table changes a count */ + for (int pass = 0; pass < 2; pass++) + { + for (k = 0; k < 256; k++) + buf[k] = pass == 0 ? (unsigned char)k : (unsigned char)(255 - k); + int a = 1, b = 1; + lw_t got = fn(buf, 256, &a, 1, 1); + + if (got.lines != ref_lines(buf, 256) || + got.words != ref_words(buf, 256, &b) || a != b) + { + printf("%s: predicate ramp pass=%d failed\n", name, pass); + fails++; + } + } + printf("%s: %s\n", name, fails ? "FAIL" : "ok"); return fails; }