shader: emit DPP row_share instead of an identity move

This commit is contained in:
Bartlomiej Wolynczyk
2026-10-06 14:22:09 +00:00
committed by nmzik
parent f3836bb831
commit 053f5fd3cc
2 changed files with 64 additions and 0 deletions
+54
View File
@@ -24904,6 +24904,56 @@ TestCase VectorDppRowXmask() {
return test;
}
TestCase VectorDppRowShare(u32 wave_size) {
using O = ShaderOpcode;
constexpr u32 sentinel = 0xaaaaaaaau;
TestCase test;
test.name = wave_size == 32 ? "VectorDppRowShareWave32" : "VectorDppRowShareWave64";
auto &code = test.code;
AppendVMovU32(&code, 1, 100);
code.push_back(EncodeVop2(0x25, 1, Vgpr(0), 1)); // v1 = 100 + lane.
code.push_back(EncodeSop1(0x04, 10, 126));
for (u32 selector = 0; selector < 16; ++selector) {
for (const bool masked : {false, true}) {
const u32 row_mask = masked ? 0xau : 0xfu;
const u32 bank_mask = masked ? 0x5u : 0xfu;
// Keep the selected source active in every row while masking destination
// lanes. Row and bank masks affect destinations, not the shared source.
const u32 source_lanes = 0x00010001u << selector;
const u32 exec[] = {masked ? 0xaaaaaaaau | source_lanes : 0xffffffffu,
masked ? 0x55555555u | source_lanes : 0xffffffffu};
AppendVMovLiteral(&code, 2, sentinel);
AppendVMovLiteral(&code, 3, sentinel);
AppendSMovLiteral(&code, 126, exec[0]);
if (wave_size == 64) AppendSMovLiteral(&code, 127, exec[1]);
code.push_back(EncodeVop1(0x01, 2, 250));
code.push_back(EncodeVop1Dpp(1, 0x150 + selector, row_mask, bank_mask));
code.push_back(EncodeVop2(0x25, 3, 250, 0));
code.push_back(EncodeVop2Dpp(1, 0x150 + selector, row_mask, bank_mask));
code.push_back(EncodeSop1(0x04, 126, 10));
for (const u32 reg : {2u, 3u}) {
AppendStoreVgprAtLaneDwordOffset(&code, reg, 0, u32(test.expected.size()));
for (u32 lane = 0; lane < wave_size; ++lane) {
const bool write = ((row_mask >> (lane / 16)) & 1u) &&
((bank_mask >> ((lane / 4) % 4)) & 1u) &&
((exec[lane / 32] >> (lane % 32)) & 1u);
const u32 source = (lane / 16) * 16 + selector;
test.expected.push_back(write ? 100 + source + (reg == 3 ? lane : 0) : sentinel);
}
}
}
}
AppendEnd(&code);
test.opcodes = {O::V_MOV_B32, O::V_ADD_NC_U32, O::S_MOV_B32, O::S_MOV_B64,
O::V_LSHLREV_B32, O::BUFFER_STORE_DWORD, O::S_ENDPGM};
test.compute_info.wave_size = wave_size;
test.compute_info.threads_num[0] = wave_size;
test.compute_info.threads_num[1] = test.compute_info.threads_num[2] = 1;
test.compute_info.thread_ids_num = 1;
test.has_compute_info = true;
return test;
}
TestCase VectorDppBankMaskPreservesDestination() {
using O = ShaderOpcode;
@@ -37124,6 +37174,8 @@ std::vector<TestCase> MakeCases() {
cases.push_back(VectorDpp8Captured(true));
AddCase(VectorDppQuadPermuteReverse);
AddCase(VectorDppRowXmask);
cases.push_back(VectorDppRowShare(32));
cases.push_back(VectorDppRowShare(64));
AddCase(VectorDppBankMaskPreservesDestination);
AddCase(VectorDppBoundsControlZeroPreservesDestination);
AddCase(Vop3FmacF32NegatedSourceAccumulates);
@@ -42803,6 +42855,8 @@ int main(int argc, char **argv) {
RunCase(&vulkan, VectorDpp8Captured(true));
RunCase(&vulkan, VectorDppQuadPermuteReverse());
RunCase(&vulkan, VectorDppRowXmask());
RunCase(&vulkan, VectorDppRowShare(32));
RunCase(&vulkan, VectorDppRowShare(64));
RunCase(&vulkan, VectorDppBankMaskPreservesDestination());
RunCase(&vulkan, VectorDppBoundsControlZeroPreservesDestination());
return 0;