From 7f66a618010c8c6bed9343de1cf35b449e24facf Mon Sep 17 00:00:00 2001 From: nmzik Date: Wed, 19 Aug 2026 20:46:31 +0200 Subject: [PATCH] shader: reject rejoining early-exit routes --- .../recompiler/frontend/cfg/ShaderCFG.cpp | 3 ++- tests/shaderCfgTests.cpp | 19 ++++++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/graphics/shader/recompiler/frontend/cfg/ShaderCFG.cpp b/src/graphics/shader/recompiler/frontend/cfg/ShaderCFG.cpp index e2a9f3fa3..3265bc5a1 100644 --- a/src/graphics/shader/recompiler/frontend/cfg/ShaderCFG.cpp +++ b/src/graphics/shader/recompiler/frontend/cfg/ShaderCFG.cpp @@ -1803,7 +1803,8 @@ bool RouteOneSharedArm(Graph& graph, uint32_t original_block_count, uint32_t out const auto continuation = graph.FindNearestCommonPostDominator(shared, body); const auto* continuation_block = graph.FindBlock(continuation); - if (continuation_block == nullptr || continuation == other) { + if (continuation_block == nullptr || continuation == other || + CanReachBefore(graph, other, continuation, UINT32_MAX)) { continue; } std::vector outer_predecessors; diff --git a/tests/shaderCfgTests.cpp b/tests/shaderCfgTests.cpp index fec5a869c..a2299f27e 100644 --- a/tests/shaderCfgTests.cpp +++ b/tests/shaderCfgTests.cpp @@ -7686,14 +7686,23 @@ void TestNewShaderRecompilerCfgExecSccSharedArm() { void TestNewShaderRecompilerCfgNestedTailEarlyExit() { const uint32_t shader[] = { - EncodeSopc(0x06, 0, 0), // outer condition + EncodeSopc(0x06, 0, 0), // preceding outer condition + EncodeSopp(0x04, 6), // preceding outer -> shared tail or inner + EncodeSopc(0x06, 1, 1), // preceding inner condition + EncodeSopp(0x04, 2), // preceding inner -> body or arm + EncodeSMovB32(2, 129), // preceding arm + EncodeSopp(0x02, 0), // preceding arm -> body + EncodeSMovB32(3, 129), // preceding body + EncodeSopp(0x02, 0), // preceding body -> shared tail + EncodeSMovB32(4, 129), // preceding shared tail + EncodeSopc(0x06, 5, 5), // outer condition EncodeSopp(0x04, 4), // outer -> right arm or inner condition - EncodeSopc(0x06, 1, 1), // inner early-exit condition + EncodeSopc(0x06, 6, 6), // inner early-exit condition EncodeSopp(0x04, 4), // inner -> exit or left arm - EncodeSMovB32(2, 129), // left arm + EncodeSMovB32(7, 129), // left arm EncodeSopp(0x02, 1), // left arm -> common tail - EncodeSMovB32(3, 129), // right arm - EncodeSMovB32(4, 129), // common tail + EncodeSMovB32(8, 129), // right arm + EncodeSMovB32(9, 129), // common tail 0xbf810000u, };