shader: translate zero-kind branches as the negated nonzero vote

This commit is contained in:
nmzik
2026-10-21 23:33:30 +02:00
parent 0f7d112545
commit da19501889
2 changed files with 8 additions and 5 deletions
@@ -739,14 +739,16 @@ void Translator::WriteCompareResult(const Decoder::Operand& operand, IR::U1 valu
void Translator::AddBranchCondition(const CFG::Graph& graph, const CFG::BasicBlock& source,
IR::Block& info) {
const auto native_condition = [&](CFG::BranchCondition kind) -> IR::U1 {
// A zero kind negates the vote of the nonzero kind that follows it in the enum.
const bool zero = kind == CFG::BranchCondition::SccZero ||
kind == CFG::BranchCondition::VccZero ||
kind == CFG::BranchCondition::ExecZero;
if (zero) kind = static_cast<CFG::BranchCondition>(static_cast<int>(kind) + 1);
IR::U1 condition;
switch (kind) {
case CFG::BranchCondition::Always: condition = IR::U1(IR::Value(true)); break;
case CFG::BranchCondition::SccZero: condition = ir.LogicalNot(ir.GetScc()); break;
case CFG::BranchCondition::SccNonZero: condition = ir.GetScc(); break;
case CFG::BranchCondition::VccZero: condition = ir.LogicalNot(ir.GetVcc()); break;
case CFG::BranchCondition::VccNonZero: condition = ir.GetVcc(); break;
case CFG::BranchCondition::ExecZero: condition = ir.LogicalNot(ir.GetExec()); break;
case CFG::BranchCondition::ExecNonZero: condition = ir.GetExec(); break;
case CFG::BranchCondition::ScalarInstruction:
EXIT_IF(instruction_branch_condition.IsEmpty());
@@ -754,7 +756,8 @@ void Translator::AddBranchCondition(const CFG::Graph& graph, const CFG::BasicBlo
break;
default: EXIT("block %u has an invalid native branch condition", source.id);
}
return IR::U1(ir.Emit(IR::ValueOpcode::ConditionRef, {condition}, kind));
const auto vote = IR::U1(ir.Emit(IR::ValueOpcode::ConditionRef, {condition}, kind));
return zero ? ir.LogicalNot(vote) : vote;
};
const auto expression = [&](auto&& self, uint32_t index) -> IR::U1 {
const auto& value = graph.expressions.at(index);
+1 -1
View File
@@ -31177,7 +31177,7 @@ TestCase ScalarBranchRestoresInactiveLanes(u32 wave_size, u32 threads, bool uppe
upper_nonzero ? O::S_CBRANCH_EXECNZ : O::S_CBRANCH_EXECZ,
O::V_READLANE_B32, O::V_LSHLREV_B32,
O::BUFFER_STORE_DWORD, O::S_ENDPGM};
test.required_spirv = {upper_nonzero ? "OpGroupNonUniformAny" : "OpGroupNonUniformAll"};
test.required_spirv = {"OpGroupNonUniformAny"};
test.compute_info.wave_size = wave_size;
test.compute_info.threads_num[0] = threads;
test.compute_info.thread_ids_num = 1;