mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-19 18:36:53 +02:00
shader: keep quiet NaNs with payload bits out of the packed f16 min/max sNaN path (#1579)
V_PK_MIN_F16 and V_PK_MAX_F16 return the quieted NaN for a signaling NaN operand and the other operand for a quiet one (per half, as V_MIN_F16 and V_MAX_F16 do). The signaling test masked the half with 0x7c00 and checked for a nonzero payload, so a quiet NaN with payload bits such as 0x7e01 was taken as signaling and returned. Mask with 0x7e00 so the quiet bit must be clear. Two more vectors in PackedMinMaxF16NanAndSignedZeroEdges cover it. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -27,7 +27,7 @@ void Translator::PackedFloat16(const Decoder::Instruction& inst, IR::ValueOpcode
|
||||
if (quiet_snan) {
|
||||
const auto quiet_snan_lane = [&](const Decoder::Operand& operand, bool high) {
|
||||
const auto bits = ReadU16LaneAsU32(operand, high, false);
|
||||
const auto exponent = ir.BitwiseAnd(bits, IR::U32(IR::Value(0x7c00u)));
|
||||
const auto exponent = ir.BitwiseAnd(bits, IR::U32(IR::Value(0x7e00u)));
|
||||
const auto payload = ir.BitwiseAnd(bits, IR::U32(IR::Value(0x01ffu)));
|
||||
const auto snan = ir.LogicalAnd(ir.IEqual(exponent, IR::U32(IR::Value(0x7c00u))),
|
||||
ir.INotEqual(payload, IR::U32(IR::Value(0u))));
|
||||
|
||||
@@ -25880,13 +25880,17 @@ TestCase PackedMinMaxF16NanAndSignedZeroEdges() {
|
||||
AppendVMovLiteral(&code, 3, 0x80007e00u);
|
||||
AppendVMovLiteral(&code, 4, 0x40007d01u);
|
||||
AppendVMovLiteral(&code, 5, 0x7d014000u);
|
||||
AppendVMovLiteral(&code, 6, 0x40007e01u);
|
||||
AppendVMovLiteral(&code, 7, 0x7e013c00u);
|
||||
|
||||
AppendVop3p(&code, 0x11, 10, Vgpr(0), Vgpr(1), 0, 0x3);
|
||||
AppendVop3p(&code, 0x12, 11, Vgpr(2), Vgpr(3), 0, 0x3);
|
||||
AppendVop3p(&code, 0x11, 12, Vgpr(4), Vgpr(5), 0, 0x3);
|
||||
AppendVop3p(&code, 0x12, 13, Vgpr(4), Vgpr(5), 0, 0x3);
|
||||
AppendVop3p(&code, 0x11, 14, Vgpr(6), Vgpr(7), 0, 0x3);
|
||||
AppendVop3p(&code, 0x12, 15, Vgpr(6), Vgpr(7), 0, 0x3);
|
||||
|
||||
for (u32 i = 0; i < 4; i++) {
|
||||
for (u32 i = 0; i < 6; i++) {
|
||||
AppendStoreVgpr(&code, 10 + i, i);
|
||||
}
|
||||
AppendEnd(&code);
|
||||
@@ -25894,7 +25898,7 @@ TestCase PackedMinMaxF16NanAndSignedZeroEdges() {
|
||||
return {"PackedMinMaxF16NanAndSignedZeroEdges",
|
||||
code,
|
||||
{},
|
||||
{0x80004000u, 0x00004000u, 0x7f017f01u, 0x7f017f01u},
|
||||
{0x80004000u, 0x00004000u, 0x7f017f01u, 0x7f017f01u, 0x40003c00u, 0x40003c00u},
|
||||
{O::V_MOV_B32, O::V_PK_MIN_F16, O::V_PK_MAX_F16,
|
||||
O::BUFFER_STORE_DWORD, O::S_ENDPGM}};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user