From ce54aa8d14c5d1b0029bc6fc155591cbe546fa45 Mon Sep 17 00:00:00 2001 From: nmzik Date: Thu, 22 Oct 2026 00:28:43 +0200 Subject: [PATCH] shader: return the first source when both 64-bit min/max inputs are NaN --- .../recompiler/backend/spirv/spirvEmitterAlu.cpp | 10 +++++----- tests/ShaderRecompilerComputeTests.cpp | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/graphics/shader/recompiler/backend/spirv/spirvEmitterAlu.cpp b/src/graphics/shader/recompiler/backend/spirv/spirvEmitterAlu.cpp index 0770c9d09..720faf9d4 100644 --- a/src/graphics/shader/recompiler/backend/spirv/spirvEmitterAlu.cpp +++ b/src/graphics/shader/recompiler/backend/spirv/spirvEmitterAlu.cpp @@ -20,11 +20,11 @@ uint32_t EmitMinMaxF64(EmitterState& state, uint32_t lhs, uint32_t rhs, bool max result = Select(state, TypeF64(state), equal, Unary(state, spv::OpBitcast, TypeF64(state), equal_bits), result); - // Non-IEEE mode selects the other operand for NaN, including rhs when both are NaN. - result = Select(state, TypeF64(state), Unary(state, spv::OpIsNan, TypeBool(state), rhs), - lhs, result); - return Select(state, TypeF64(state), Unary(state, spv::OpIsNan, TypeBool(state), lhs), - rhs, result); + // Non-IEEE mode selects the other operand for NaN, and lhs when both are NaN. + result = Select(state, TypeF64(state), Unary(state, spv::OpIsNan, TypeBool(state), lhs), + rhs, result); + return Select(state, TypeF64(state), Unary(state, spv::OpIsNan, TypeBool(state), rhs), + lhs, result); } uint32_t EmitMulHigh(EmitterState& state, uint32_t lhs, uint32_t rhs, bool signed_value) { diff --git a/tests/ShaderRecompilerComputeTests.cpp b/tests/ShaderRecompilerComputeTests.cpp index 0055aed7d..f5fe6a0ee 100644 --- a/tests/ShaderRecompilerComputeTests.cpp +++ b/tests/ShaderRecompilerComputeTests.cpp @@ -28735,7 +28735,7 @@ TestCase VectorFractF64CapturedAndEdges() { TestCase VectorMinMaxF64CapturedAndEdges() { using O = ShaderOpcode; - // MODE.IEEE=0: select the numeric operand, or the second NaN unchanged. + // MODE.IEEE=0: select the numeric operand, or the first NaN unchanged. constexpr uint64_t positive_zero = 0, negative_zero = 0x8000000000000000ull; constexpr uint64_t one = 0x3ff0000000000000ull, minus_two = 0xc000000000000000ull; constexpr uint64_t qnan = 0x7ff8123456789abcull, snan = 0xfff0000000000042ull; @@ -28749,7 +28749,7 @@ TestCase VectorMinMaxF64CapturedAndEdges() { {positive_zero, positive_zero, positive_zero, positive_zero}, {qnan, one, one, one}, {one, qnan, one, one}, {snan, minus_two, minus_two, minus_two}, {minus_two, snan, minus_two, minus_two}, - {qnan, snan, snan, snan}, {snan, qnan, qnan, qnan}, + {qnan, snan, qnan, qnan}, {snan, qnan, snan, snan}, {infinity, one, one, infinity}, {infinity | negative_zero, one, infinity | negative_zero, one}, {0x3fe0000000000000ull, one, 0x3fe0000000000000ull, one},