tests: complete the mldsa SIMD dispatch ladder

Upstream added an AVX512 arm above the AVX2 one, and the ladder only ever
cleared AVX2/BMI2 -- so the AVX512 arm won every row and the arms below it
stopped being reached, costing 64 conditions.

Three fixes: USE_INTEL_AVX512() is IS_INTEL_AVX512() && IS_INTEL_AVX512_BW(),
so the F and BW bits are now cleared separately to give that decision's three
operands their own rows; a row clears AVX512_VBMI for the new VBMI arm; and
CPUID_INTEL is forced on, because SHA3_USE_AVX2() is gated on IS_CPU_INTEL()
and its true side is otherwise unreachable on an AMD host. Rows can now set
bits as well as clear them.

wc_mldsa.c 292/579 -> 463/579.
This commit is contained in:
Daniele Lacamera
2026-08-07 09:27:42 +02:00
parent 1f5887183c
commit a9212acce9
+22 -4
View File
@@ -709,6 +709,7 @@ static void wb_oid_to_level(void)
*
* wc_mldsa.c selects an implementation with
*
* if (IS_INTEL_AVX512_VBMI(cpuid_flags) && (SAVE_VECTOR_REGISTERS2() == 0))
* if (IS_INTEL_AVX2(cpuid_flags) && (SAVE_VECTOR_REGISTERS2() == 0))
* if (IS_INTEL_AVX2(cpuid_flags) && IS_INTEL_BMI2(cpuid_flags) && ...)
* if ((k == N) && (l == N) && IS_INTEL_AVX2(cpuid_flags) && ...)
@@ -790,14 +791,30 @@ static void wb_dispatch_rows(void)
int saved_intr = wb_intr_ret;
WC_RNG rng;
unsigned i, t;
/* USE_INTEL_AVX512(f) is itself IS_INTEL_AVX512(f) && IS_INTEL_AVX512_BW(f)
* (cpuid.h), so each AVX512 dispatch is a three-condition decision and the
* F and BW bits need to be cleared separately. SHA3_USE_AVX2(f) is
* IS_INTEL_AVX2(f) && IS_CPU_INTEL(f): its vendor operand is false on any
* AMD host, so CPUID_INTEL is forced on for the rows that need its true
* side -- the arm behind it is plain AVX2, which runs anywhere AVX2 does. */
static const struct {
cpuid_flags_t set;
cpuid_flags_t clear;
int intr;
} rows[] = {
{ 0, 0 }, /* richest arm */
{ 0, 1 }, /* save refused */
{ CPUID_BMI2, 0 }, /* AVX2 without BMI2 */
{ CPUID_AVX2 | CPUID_BMI2, 0 }, /* portable C */
{ CPUID_INTEL, 0, 0 }, /* richest arm */
{ CPUID_INTEL, 0, 1 }, /* save refused */
{ CPUID_INTEL, CPUID_AVX512_BW, 0 }, /* F set, BW clear */
{ CPUID_INTEL, CPUID_AVX512, 0 }, /* F clear */
{ CPUID_INTEL, CPUID_AVX512_VBMI, 0 }, /* no VBMI */
{ CPUID_INTEL, CPUID_AVX512 | CPUID_AVX512_BW |
CPUID_AVX512_VBMI, 0 }, /* -> AVX2 arm */
{ CPUID_INTEL, CPUID_AVX512 | CPUID_AVX512_BW |
CPUID_AVX512_VBMI | CPUID_BMI2, 0 }, /* AVX2 no BMI2 */
{ CPUID_INTEL, CPUID_AVX512 | CPUID_AVX512_BW |
CPUID_AVX512_VBMI | CPUID_BMI2 |
CPUID_AVX2, 0 }, /* portable C */
{ 0, CPUID_INTEL, 0 }, /* non-Intel vendor */
};
if (wc_InitRng(&rng) != 0) {
@@ -808,6 +825,7 @@ static void wb_dispatch_rows(void)
for (i = 0; i < sizeof(rows) / sizeof(rows[0]); i++) {
cpuid_flags = WC_CPUID_INITIALIZER;
(void)cpuid_get_flags_ex(&cpuid_flags);
cpuid_flags |= rows[i].set;
cpuid_flags &= (cpuid_flags_t)~rows[i].clear;
wb_intr_ret = rows[i].intr;