From 515fb1241b7845735aeb61f9ead4de9b0fdb0bee Mon Sep 17 00:00:00 2001 From: Lander Gallastegi Date: Thu, 10 Apr 2025 12:43:55 +0200 Subject: [PATCH] Consider else branches for subprogram --- src/shader_recompiler/ir/subprogram.cpp | 31 ++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/shader_recompiler/ir/subprogram.cpp b/src/shader_recompiler/ir/subprogram.cpp index 757420da2..bd3824024 100644 --- a/src/shader_recompiler/ir/subprogram.cpp +++ b/src/shader_recompiler/ir/subprogram.cpp @@ -118,11 +118,40 @@ void SubProgram::AddPhi(Inst* orig_phi, Inst* phi) { } return {cond1, cond0}; }; + const auto is_negated_cond = [](Inst* ref1, Inst* ref2) { + IR::Value cond1 = ref1->Arg(0); + IR::Value cond2 = ref2->Arg(0); + if (cond1.IsImmediate() || cond2.IsImmediate()) { + if (!cond1.IsImmediate() || !cond2.IsImmediate()) { + return false; + } + return cond1.U1() != cond2.U1(); + } + Inst* cond1_inst = cond1.InstRecursive(); + Inst* cond2_inst = cond2.InstRecursive(); + if (cond1_inst->GetOpcode() == Opcode::LogicalNot) { + return cond1_inst->Arg(0) == cond2; + } + if (cond2_inst->GetOpcode() == Opcode::LogicalNot) { + return cond2_inst->Arg(0) == cond1; + } + return false; + }; const auto& [start_cond, target_cond] = get_conds(); const Block::ConditionalData* cond = &start_cond; while (cond->depth > target_cond.depth) { if (cond->asl_node->type == AbstractSyntaxNode::Type::If) { - AddInst(cond->asl_node->data.if_node.cond.InstRecursive()); + Inst* cond_ref_inst = cond->asl_node->data.if_node.cond.InstRecursive(); + AddInst(cond_ref_inst); + // Check if the condition has an else branch, and add it. + Block* merge_block = cond->asl_node->data.if_node.merge; + Inst* else_cond_ref_inst = &merge_block->back(); + if (else_cond_ref_inst->GetOpcode() == Opcode::ConditionRef) { + // Check if one condition is the negation of the other. + if (is_negated_cond(cond_ref_inst, else_cond_ref_inst)) { + AddInst(else_cond_ref_inst); + } + } } else if (cond->asl_node->type == AbstractSyntaxNode::Type::Loop) { // In case of loop, we need to add the loop itself and also // the break conditions.