cfg: Add one more divergence case

* Seen in RDR shaders
This commit is contained in:
IndecisiveTurtle 2024-08-18 00:07:24 +03:00
parent 63938ba8dd
commit 68c465813c
2 changed files with 6 additions and 3 deletions

View File

@ -37,6 +37,7 @@ static IR::Condition MakeCondition(Opcode opcode) {
return IR::Condition::Execnz; return IR::Condition::Execnz;
case Opcode::S_AND_SAVEEXEC_B64: case Opcode::S_AND_SAVEEXEC_B64:
case Opcode::S_ANDN2_B64: case Opcode::S_ANDN2_B64:
case Opcode::V_CMPX_NE_U32:
return IR::Condition::Execnz; return IR::Condition::Execnz;
default: default:
return IR::Condition::True; return IR::Condition::True;
@ -93,7 +94,8 @@ void CFG::EmitDivergenceLabels() {
// While this instruction does not save EXEC it is often used paired // While this instruction does not save EXEC it is often used paired
// with SAVEEXEC to mask the threads that didn't pass the condition // with SAVEEXEC to mask the threads that didn't pass the condition
// of initial branch. // of initial branch.
inst.opcode == Opcode::S_ANDN2_B64; inst.opcode == Opcode::S_ANDN2_B64 ||
inst.opcode == Opcode::V_CMPX_NE_U32;
}; };
const auto is_close_scope = [](const GcnInst& inst) { const auto is_close_scope = [](const GcnInst& inst) {
// Closing an EXEC scope can be either a branch instruction // Closing an EXEC scope can be either a branch instruction
@ -187,7 +189,8 @@ void CFG::LinkBlocks() {
const auto end_inst{block.end_inst}; const auto end_inst{block.end_inst};
// Handle divergence block inserted here. // Handle divergence block inserted here.
if (end_inst.opcode == Opcode::S_AND_SAVEEXEC_B64 || if (end_inst.opcode == Opcode::S_AND_SAVEEXEC_B64 ||
end_inst.opcode == Opcode::S_ANDN2_B64) { end_inst.opcode == Opcode::S_ANDN2_B64 ||
end_inst.opcode == Opcode::V_CMPX_NE_U32) {
// Blocks are stored ordered by address in the set // Blocks are stored ordered by address in the set
auto next_it = std::next(it); auto next_it = std::next(it);
auto* target_block = &(*next_it); auto* target_block = &(*next_it);

View File

@ -166,7 +166,7 @@ struct Liverpool {
static constexpr auto* GetBinaryInfo(const Shader& sh) { static constexpr auto* GetBinaryInfo(const Shader& sh) {
const auto* code = sh.template Address<u32*>(); const auto* code = sh.template Address<u32*>();
const auto* bininfo = std::bit_cast<const BinaryInfo*>(code + (code[1] + 1) * 2); const auto* bininfo = std::bit_cast<const BinaryInfo*>(code + (code[1] + 1) * 2);
ASSERT_MSG(bininfo->Valid(), "Invalid shader binary header"); //ASSERT_MSG(bininfo->Valid(), "Invalid shader binary header");
return bininfo; return bininfo;
} }