diff --git a/src/shader_recompiler/frontend/control_flow_graph.cpp b/src/shader_recompiler/frontend/control_flow_graph.cpp index 60b14ff8f..b53db9e94 100644 --- a/src/shader_recompiler/frontend/control_flow_graph.cpp +++ b/src/shader_recompiler/frontend/control_flow_graph.cpp @@ -70,8 +70,9 @@ static bool IgnoresExecMask(const GcnInst& inst) { static std::optional ResolveSetPcTarget(std::span list, u32 setpc_index, std::span pc_map) { - if (setpc_index < 3) + if (setpc_index < 3) { return std::nullopt; + } const auto& getpc = list[setpc_index - 3]; const auto& arith = list[setpc_index - 2]; @@ -96,7 +97,7 @@ static std::optional ResolveSetPcTarget(std::span list, u32 const u32 base_pc = pc_map[setpc_index - 3] + getpc.length; const u32 result_pc = static_cast(static_cast(base_pc) + signed_offset); - LOG_INFO(Render_Recompiler, "SetPC target: {} + {} = {}", base_pc, signed_offset, result_pc); + LOG_DEBUG(Render_Recompiler, "SetPC target: {} + {} = {}", base_pc, signed_offset, result_pc); return result_pc & ~0x3u; } @@ -124,10 +125,18 @@ void CFG::EmitLabels() { if (inst.IsUnconditionalBranch()) { u32 target = inst.BranchTarget(pc); if (inst.opcode == Opcode::S_SETPC_B64) { - if (auto t = ResolveSetPcTarget(inst_list, i, index_to_pc)) + if (auto t = ResolveSetPcTarget(inst_list, i, index_to_pc)) { target = *t; + } else { + ASSERT_MSG( + false, + "S_SETPC_B64 without a resolvable offset at PC {:#x} (Index {}): Involved " + "instructions not recognized or invalid pattern", + pc, i); + } } AddLabel(target); + // Emit this label so that the block ends with the branching instruction AddLabel(pc + inst.length); } else if (inst.IsConditionalBranch()) { const u32 true_label = inst.BranchTarget(pc); @@ -135,7 +144,8 @@ void CFG::EmitLabels() { AddLabel(true_label); AddLabel(false_label); } else if (inst.opcode == Opcode::S_ENDPGM) { - AddLabel(pc + inst.length); + const u32 next_label = pc + inst.length; + AddLabel(next_label); } pc += inst.length; diff --git a/src/shader_recompiler/frontend/instruction.cpp b/src/shader_recompiler/frontend/instruction.cpp index 609e3b034..246c2b85a 100644 --- a/src/shader_recompiler/frontend/instruction.cpp +++ b/src/shader_recompiler/frontend/instruction.cpp @@ -18,7 +18,7 @@ bool GcnInst::IsTerminateInstruction() const { } bool GcnInst::IsUnconditionalBranch() const { - return opcode == Opcode::S_BRANCH or opcode == Opcode::S_SETPC_B64; + return opcode == Opcode::S_BRANCH || opcode == Opcode::S_SETPC_B64; } bool GcnInst::IsFork() const { diff --git a/src/shader_recompiler/frontend/translate/scalar_flow.cpp b/src/shader_recompiler/frontend/translate/scalar_flow.cpp index 45d1be2dc..cd1cf51f0 100644 --- a/src/shader_recompiler/frontend/translate/scalar_flow.cpp +++ b/src/shader_recompiler/frontend/translate/scalar_flow.cpp @@ -19,7 +19,6 @@ void Translator::EmitFlowControl(u32 pc, const GcnInst& inst) { case Opcode::S_GETPC_B64: return S_GETPC_B64(pc, inst); case Opcode::S_SETPC_B64: - return; case Opcode::S_WAITCNT: case Opcode::S_NOP: case Opcode::S_ENDPGM: