From cd9bb569a3400eb833c77ed5dc1f34d7522bbea9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 19 Sep 2026 13:21:36 -0600 Subject: [PATCH] unittest: don't pin CleanNaNInfs to one implementation's output The contract is only that a bad lane becomes something that yields zero when multiplied by zero, by whatever route is cheapest. SSE2 clamps to +-FLT_MAX, NEON, LSX and the scalar fallback zero the lane - both fine. Check that property, and that good lanes are untouched. Co-Authored-By: Claude Opus 5 (1M context) --- unittest/TestCrossSIMD.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/unittest/TestCrossSIMD.cpp b/unittest/TestCrossSIMD.cpp index e584bf762b..9ad066a315 100644 --- a/unittest/TestCrossSIMD.cpp +++ b/unittest/TestCrossSIMD.cpp @@ -391,9 +391,15 @@ static bool TestVec4F32NaNInf() { EXPECT_TRUE(std::isinf(result[2])); EXPECT_TRUE(std::isinf(result[3])); + // The contract is just "a value that yields zero when multiplied by zero" - whatever is + // cheapest to get there. So the implementations legitimately differ on what a bad lane + // becomes: SSE2 clamps to +-FLT_MAX, NEON, LSX and the scalar fallback zero it. Check the + // property rather than the value, and that good lanes are left alone. v.CleanNaNInfs().Store(result); - static const float known_clean[4] = { 1.0f, 0.0f, 0.0f, 0.0f }; - if (!CompareFloats(result, known_clean, 4, __LINE__)) return false; + EXPECT_EQ_FLOAT(result[0], 1.0f); + for (int i = 0; i < 4; i++) { + EXPECT_EQ_FLOAT(result[i] * 0.0f, 0.0f); + } return true; }