shader: preserve raw VCC bits in S_MOV_B64 (#418)

* shader: preserve raw VCC bits in S_MOV_B64

* fix(shader): centralize scalar U64 mask provenance

---------

Co-authored-by: nmzik <Nmzik@mail.ru>
This commit is contained in:
nomolao2-cell
2026-08-30 17:04:16 -06:00
committed by GitHub
parent dc5b7c19a6
commit 6758d67942
13 changed files with 444 additions and 185 deletions
+17 -11
View File
@@ -9470,10 +9470,12 @@ void TestTypedEntryStateIsMinimal() {
error.c_str());
uint32_t set_exec = 0;
uint32_t set_exec_mask_tag = 0;
uint32_t set_exec_lo = 0;
uint32_t set_exec_hi = 0;
uint32_t ballots = 0;
IR::Value exec;
IR::Value exec_mask_tag;
IR::Value exec_lo;
IR::Value exec_hi;
for (const auto *block : values.blocks) {
@@ -9486,6 +9488,10 @@ void TestTypedEntryStateIsMinimal() {
set_exec++;
exec = inst.Arg(0).Resolve();
break;
case IR::ValueOpcode::SetExecMaskTag:
set_exec_mask_tag++;
exec_mask_tag = inst.Arg(0).Resolve();
break;
case IR::ValueOpcode::SetExecLo:
set_exec_lo++;
exec_lo = inst.Arg(0).Resolve();
@@ -9500,6 +9506,7 @@ void TestTypedEntryStateIsMinimal() {
case IR::ValueOpcode::SetVectorRegister:
case IR::ValueOpcode::SetScc:
case IR::ValueOpcode::SetVcc:
case IR::ValueOpcode::SetVccMaskValidTag:
case IR::ValueOpcode::SetVccLo:
case IR::ValueOpcode::SetVccHi:
case IR::ValueOpcode::SetM0:
@@ -9510,8 +9517,9 @@ void TestTypedEntryStateIsMinimal() {
}
}
}
Check(set_exec == 1u && set_exec_lo == 1u && set_exec_hi == 1u &&
ballots == 0u && exec.IsImmediate() && exec.U1() &&
Check(set_exec == 1u && set_exec_mask_tag == 1u && set_exec_lo == 1u &&
set_exec_hi == 1u && ballots == 0u && exec.IsImmediate() &&
exec.U1() && exec_mask_tag.IsImmediate() && exec_mask_tag.U1() &&
exec_lo.IsImmediate() && exec_lo.U32() == 1u &&
exec_hi.IsImmediate() && exec_hi.U32() == 0u,
"typed entry is not the local {1,0} invocation mask");
@@ -10372,11 +10380,8 @@ void TestNewShaderRecompilerPerInvocationMasksWithoutMirrors() {
error.c_str());
CheckSpirvBinaryValidates(result.spirv);
const auto wqm_source = DisassembleSpirvBinary(result.spirv);
Check(Common::ContainsStr(wqm_source, "OpCapability GroupNonUniformBallot") &&
Common::ContainsStr(wqm_source, "OpGroupNonUniformBallot"),
"per-invocation scalar WQM omitted its subgroup ballot capability");
Check(SpirvInstructionOpcodeCount(result.spirv, 132u) == 2u,
"wave64 WQM did not compact exactly two ballot words");
Check(!Common::ContainsStr(wqm_source, "OpGroupNonUniformBallot"),
"raw scalar WQM reconstructed its source from invocation provenance");
auto wave32_options = options;
wave32_options.wave_size = 32u;
@@ -10384,8 +10389,9 @@ void TestNewShaderRecompilerPerInvocationMasksWithoutMirrors() {
&error),
error.c_str());
CheckSpirvBinaryValidates(result.spirv);
Check(SpirvInstructionOpcodeCount(result.spirv, 132u) == 1u,
"wave32 WQM retained the unused high ballot-word expansion");
Check(!Common::ContainsStr(DisassembleSpirvBinary(result.spirv),
"OpGroupNonUniformBallot"),
"wave32 raw scalar WQM reconstructed invocation provenance");
const uint32_t cross_lane_shader[] = {
EncodeSop2(0x25, 126, 132, 128), // s_bfm_b64 exec, 4, 0
@@ -12488,8 +12494,8 @@ void TestNewShaderRecompilerSpirvSizeBaselines() {
.conditional_branches = 1,
.ballots = 1},
ShaderType::Vertex);
Check(Common::ContainsStr(wqm_result.ir_dump, "WqmMask"),
"WQM size fixture no longer reaches per-invocation WqmMask IR");
Check(Common::ContainsStr(wqm_result.ir_dump, "WqmU64"),
"WQM size fixture no longer reaches raw WqmU64 IR");
const uint32_t dispatcher[] = {
EncodeSopp(0x05, 2), // entry -> B, fallthrough A