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.
This commit is contained in:
2026-08-29 17:07:42 -04:00
parent ae5068d4e7
commit 6ad747dee7
+30 -6
View File
@@ -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;
}