Files
AnyPS5/core
AlxcBTWandClaude Opus 5.5 4df387d0c1 fix(recompiler): reject a loop-exit pass result that is not structured
The third structurize pass, which routes loop exits that leave the loop
before they meet, runs only when the plain and the privatized pass
throw, and its result was used without a check. Merged with #2471, it
turns some of those budget failures into graphs that spirv-val
rejects. In this one, selection 12 of the result lies in the selection
at 7 and branches to 7's merge block 13:

  {{1}, {2, 3}, {4}, {5}, {6, 7}, {}, {8, 9}, {10, 11}, {1}, {12, 4},
   {5}, {13}, {8, 14}, {15, 16}, {7}, {13}, {4}}

  block 12 exits the selection headed by block 12, but not via a
  structured exit

hasStructuredConstructs checks the third pass's result against the
structured control-flow rules of the SPIR-V specification (2.11), with
dominance and post-dominance taken over branch, merge and continue
edges. Back edges come only from a loop's continue block. A conditional
without a merge breaks or continues its innermost loop. A header
strictly dominates its merge, and a loop header its continue block. A
construct contains the merge of every header inside it and is entered
only through its header. It is left only to its own merge or to the
innermost loop's merge or continue block, and a continue construct only
to its loop's header or merge. When the result fails, the second pass's
error is reported, as when the third pass throws. The first two passes
are unchanged.

Differential fuzz with the structured-program generator and random
reducible graphs. Oracle: exact post-dominators,
requireStructuredBranches, merges dominated by their headers, the
original's executions, and spirv-val (SPIRV-Tools v2026.4).
- Against 9fa7d06a: the same outcome and output on every graph. That
  covers 100,000 random graphs at 0 words and with one block at 1000,
  and 30,000 programs at 16 and at 1000 words per block, each also with
  one block at 1000.
- Merged with #2471, the same 30,000 programs: the third pass had made
  41, 42 and 45 of them invalid (16 words, 16 with one block at 1000,
  1000 words). These end in #2471's own error again, and nothing else
  changes. The 1, 1 and 18 graphs that d59a9167 merged with #2471
  already structures invalidly come from the first two passes and stay
  as they are.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-11 10:00:06 -03:00
..