shader: V_CMPX_NE_I64

This commit is contained in:
nmzik
2026-08-23 00:59:44 +02:00
parent 3e25eb0998
commit a610528075
5 changed files with 72 additions and 2 deletions
@@ -389,6 +389,7 @@ enum class Opcode {
V_CMP_EQ_I64, V_CMP_EQ_I64,
V_CMP_GT_U64, V_CMP_GT_U64,
V_CMP_NE_U64, V_CMP_NE_U64,
V_CMPX_NE_I64,
V_CMPX_NE_U64, V_CMPX_NE_U64,
V_CMPX_LT_U32, V_CMPX_LT_U32,
V_CMPX_EQ_U32, V_CMPX_EQ_U32,
@@ -229,6 +229,7 @@ constexpr VopcOpcodeInfo VOPC_OPCODE_LIST[] = {
{0xc3u, Opcode::V_CMP_LE_U32}, {0xc4u, Opcode::V_CMP_GT_U32}, {0xc3u, Opcode::V_CMP_LE_U32}, {0xc4u, Opcode::V_CMP_GT_U32},
{0xc5u, Opcode::V_CMP_NE_U32}, {0xc6u, Opcode::V_CMP_GE_U32}, {0xc5u, Opcode::V_CMP_NE_U32}, {0xc6u, Opcode::V_CMP_GE_U32},
{0xc7u, Opcode::V_CMP_T_U32}, {0xa2u, Opcode::V_CMP_EQ_I64, false}, {0xc7u, Opcode::V_CMP_T_U32}, {0xa2u, Opcode::V_CMP_EQ_I64, false},
{0xb5u, Opcode::V_CMPX_NE_I64, false},
{0xd1u, Opcode::V_CMPX_LT_U32}, {0xd2u, Opcode::V_CMPX_EQ_U32}, {0xd1u, Opcode::V_CMPX_LT_U32}, {0xd2u, Opcode::V_CMPX_EQ_U32},
{0xd3u, Opcode::V_CMPX_LE_U32}, {0xd4u, Opcode::V_CMPX_GT_U32}, {0xd3u, Opcode::V_CMPX_LE_U32}, {0xd4u, Opcode::V_CMPX_GT_U32},
{0xd5u, Opcode::V_CMPX_NE_U32}, {0xd6u, Opcode::V_CMPX_GE_U32}, {0xd5u, Opcode::V_CMPX_NE_U32}, {0xd6u, Opcode::V_CMPX_GE_U32},
@@ -1499,6 +1500,7 @@ bool IsVopcCompareExec(Opcode opcode) {
case Opcode::V_CMPX_GT_U32: case Opcode::V_CMPX_GT_U32:
case Opcode::V_CMPX_NE_U32: case Opcode::V_CMPX_NE_U32:
case Opcode::V_CMPX_GE_U32: case Opcode::V_CMPX_GE_U32:
case Opcode::V_CMPX_NE_I64:
case Opcode::V_CMPX_NE_U64: case Opcode::V_CMPX_NE_U64:
case Opcode::V_CMPX_LT_F16: case Opcode::V_CMPX_LT_F16:
case Opcode::V_CMPX_EQ_F16: case Opcode::V_CMPX_EQ_F16:
@@ -338,6 +338,7 @@ constexpr LowerMap LOWER_OPS[] = {
{Decoder::Opcode::V_CMP_EQ_I64, Opcode::CompareEqU64}, {Decoder::Opcode::V_CMP_EQ_I64, Opcode::CompareEqU64},
{Decoder::Opcode::V_CMP_GT_U64, Opcode::CompareGtU64}, {Decoder::Opcode::V_CMP_GT_U64, Opcode::CompareGtU64},
{Decoder::Opcode::V_CMP_NE_U64, Opcode::CompareNeU64}, {Decoder::Opcode::V_CMP_NE_U64, Opcode::CompareNeU64},
{Decoder::Opcode::V_CMPX_NE_I64, Opcode::CompareNeU64},
{Decoder::Opcode::V_CMPX_NE_U64, Opcode::CompareNeU64}, {Decoder::Opcode::V_CMPX_NE_U64, Opcode::CompareNeU64},
{Decoder::Opcode::V_CMPX_LT_U32, Opcode::CompareMaskLtU32}, {Decoder::Opcode::V_CMPX_LT_U32, Opcode::CompareMaskLtU32},
{Decoder::Opcode::V_CMPX_EQ_U32, Opcode::CompareMaskEqU32}, {Decoder::Opcode::V_CMPX_EQ_U32, Opcode::CompareMaskEqU32},
+31
View File
@@ -14748,6 +14748,36 @@ TestCase VectorVopcCmpxNeU64CapturedExecMask() {
return test; return test;
} }
TestCase VectorVop3CmpxNeI64CapturedExecMask() {
using O = ShaderOpcode;
std::vector<u32> code;
AppendVMovU32(&code, 7, 0);
AppendVMovU32(&code, 8, 0);
AppendVMovU32(&code, 31, 0);
code.push_back(0xd4b5007eu);
code.push_back(0x00020e80u); // v_cmpx_ne_i64 exec, 0, v[7:8]
AppendBufferStoreDword(&code, 8, 31);
code.push_back(EncodeSMovB32(126, InlineU32(1)));
AppendVMovU32(&code, 8, 1);
AppendVMovU32(&code, 31, 4);
code.push_back(0xd4b5007eu);
code.push_back(0x00020e80u); // v_cmpx_ne_i64 exec, 0, v[7:8]
AppendBufferStoreDword(&code, 8, 31);
AppendEnd(&code);
TestCase test{"VectorVop3CmpxNeI64CapturedExecMask",
code,
{0x11223344u, 0x55667788u},
{0x11223344u, 1u},
{O::V_MOV_B32, O::V_CMPX_NE_I64, O::BUFFER_STORE_DWORD,
O::S_MOV_B32, O::S_ENDPGM}};
test.decoded_counts = {{"V_CMPX_NE_I64 exec_lo, 0, v7", 2}};
test.native_ir_counts = {{"CompareNeU64 exec_lo, 0x00000000, v7", 2}};
return test;
}
TestCase VectorVop3CompareGtU64OnGpu() { TestCase VectorVop3CompareGtU64OnGpu() {
using O = ShaderOpcode; using O = ShaderOpcode;
@@ -19593,6 +19623,7 @@ std::vector<TestCase> MakeCases() {
AddCase(VectorVop3CompareGtU64OnGpu); AddCase(VectorVop3CompareGtU64OnGpu);
AddCase(VectorVop3CompareNeU64OnGpu); AddCase(VectorVop3CompareNeU64OnGpu);
AddCase(VectorVopcCmpxNeU64CapturedExecMask); AddCase(VectorVopcCmpxNeU64CapturedExecMask);
AddCase(VectorVop3CmpxNeI64CapturedExecMask);
AddCase(VectorCompareClassF32); AddCase(VectorCompareClassF32);
AddCase(VectorCompareF16Ops); AddCase(VectorCompareF16Ops);
AddCase(Vop2SdwaCndmaskSourceModifier); AddCase(Vop2SdwaCndmaskSourceModifier);
+37 -2
View File
@@ -4044,8 +4044,9 @@ void TestNewShaderDecoderArchitecture() {
} }
void TestNewShaderRecompilerRejectsDppOn64BitCompares() { void TestNewShaderRecompilerRejectsDppOn64BitCompares() {
const uint32_t opcodes[] = {0xa2u, 0xe4u, 0xe5u, const uint32_t opcodes[] = {
0xf5u}; // eq_i64, gt_u64, ne_u64, cmpx_ne_u64 0xa2u, 0xb5u, 0xe4u, 0xe5u,
0xf5u}; // eq_i64, cmpx_ne_i64, gt_u64, ne_u64, cmpx_ne_u64
for (const auto opcode : opcodes) { for (const auto opcode : opcodes) {
const uint32_t shader[] = { const uint32_t shader[] = {
EncodeVopc(opcode, 250u, 0u), // DPP escape in SRC0 EncodeVopc(opcode, 250u, 0u), // DPP escape in SRC0
@@ -8367,6 +8368,40 @@ void TestNewShaderRecompilerU64PairLowering() {
CompileResult result; CompileResult result;
std::string error; std::string error;
const uint32_t cmpx_i64_shader[] = {
0xd4b5007eu, 0x00020e80u, // v_cmpx_ne_i64 exec, 0, v[7:8]
EncodeSopp(0x01),
};
Decoder::Instruction decoded_cmpx_i64;
Check(Decoder::DecodeInstruction(cmpx_i64_shader, 0u, decoded_cmpx_i64,
&error),
error.c_str());
Check(decoded_cmpx_i64.opcode == Decoder::Opcode::V_CMPX_NE_I64 &&
decoded_cmpx_i64.dst.kind == Decoder::OperandKind::ExecLo &&
decoded_cmpx_i64.src0.value == 0u &&
decoded_cmpx_i64.src1.kind == Decoder::OperandKind::Vgpr &&
decoded_cmpx_i64.src1.reg == 7u,
"decoder rejected captured VOP3 V_CMPX_NE_I64 fields");
Check(TryRecompile(cmpx_i64_shader, options, result, &error), error.c_str());
Check(Common::ContainsStr(result.decoded_dump,
"V_CMPX_NE_I64 exec_lo, 0, v7"),
"captured VOP3 V_CMPX_NE_I64 was not present in the decoded dump");
Decoder::Program decoded_i64_program;
CFG::Graph graph_i64;
IR::Program native_i64;
Check(Decoder::DecodeProgram(cmpx_i64_shader, decoded_i64_program, &error),
error.c_str());
Check(CFG::BuildGraph(decoded_i64_program, graph_i64, &error) &&
CFG::Structurize(graph_i64, &error),
error.c_str());
Check(IR::LowerProgram(decoded_i64_program, graph_i64, ShaderType::Compute,
64u, native_i64, &error),
error.c_str());
Check(Common::ContainsStr(IR::ProgramToString(native_i64),
"CompareNeU64 exec_lo, 0x00000000, v7"),
"V_CMPX_NE_I64 did not lower to masked 64-bit inequality");
CheckSpirvBinaryValidates(result.spirv);
const uint32_t cmpx_shader[] = { const uint32_t cmpx_shader[] = {
0x7dea0e80u, // v_cmpx_ne_u64 exec, 0, v[7:8] 0x7dea0e80u, // v_cmpx_ne_u64 exec, 0, v[7:8]
EncodeSopp(0x01), EncodeSopp(0x01),