Trace the invalid SPIR-V emitted for the real 0x6c326400 and
0x090291ef00 compute shaders back to natural-loop construction. A guest
conditional could serve as both an OpLoopMerge and OpSelectionMerge
header, while multiple native latches could produce more than one SPIR-V
backedge for a loop.
Canonicalize those RDNA2 control-flow shapes before merge splitting:
- join multiple latches through one empty continue block
- put an internal guest-header selection behind an empty loop header
- rebuild CFG analyses after each bounded rewrite
This follows shadPS4's dedicated loop header/continue architecture
without introducing a dispatcher or compatibility fallback. Add focused
CFG and SPIR-V validation tests for both real failure shapes.
Validation:
- shader_cfg_tests --loop-canonicalization-only
- shader_cfg_tests --loop-break-merge-only
- shader_recompiler_compute_tests
- spirv-val Vulkan 1.1 for regenerated 0x6c326400 and 0x090291ef00
- launch.json runtime advanced continuously to frame 846 without fatal,
crash, or Vulkan validation error
The no-argument CFG suite still exposes the independently reproducible,
loop-free cube descriptor identity failure in the concurrent dirty tree.
Emit innermost break, continue, and repeat conditionals without selection
merges, matching SPIR-V structured-loop rules and shadPS4's control-flow
model. Split nested construct merges that would otherwise alias an outer
merge or continue target, using the full dominance-defined construct.
Add focused regressions for early loop control, nested local and nonlocal
exits, conditional latches, illegal mixed exits, and acyclic exit tails.
The focused suite passes embedded Vulkan 1.2 validation. The real
0x6c341200 compute shader now structurizes to 61 blocks and its dumped
98,650-word module passes standalone spirv-val.