Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 14, 2026

A continue statement inside a switch nested within a for loop generates invalid SPIR-V that fails validation: "block exits the selection but not via a structured exit."

for (int i = 0; i < 3; ++i) {
    switch (i) {
        case 0: continue;  // Breaks SPIR-V structured control flow
    }
}

Root Cause

Commit 412d347 added continueBlock to the exitBlocks set when processing nested constructs but never removed it. This caused the continue block to persist in the global set, affecting subsequent region processing.

Changes

  • slang-ir-eliminate-multilevel-break.cpp: Added cleanup to remove continueBlock from exitBlocks after processing each region, matching the existing cleanup pattern for info.exitBlocks
  • tests/bugs/for-loop-switch-continue.slang: Added regression test

The fix ensures proper SPIR-V structured control flow by preventing the continue block from leaking across region boundaries.

Original prompt

This section details on the original issue you should resolve

<issue_title>For loop continue inside a switch breaks structured control flow</issue_title>
<issue_description># Issue Description
Related to #8685, but this one is a regression. The repro code was fine with v2025.21.2, but it's broken in v2025.24.3.

Reproducer Code

[shader("fragment")]
float main(): SV_Target0 {
    float sum = 0;

    for (int i = 0; i < 1; ++i) {
        sum += 1;

        switch (i) {
            case 0: {
                continue;
            }
        }
    }

    return sum;
}
slangc a.slang -target spirv -O2 -o out.spv && spirv-val --target-env vulkan1.2 out.spv
error: line 45: block <ID> '28[%28]' exits the selection headed by <ID> '25[%25]', but not via a structured exit
  %28 = OpLabel

Environment

  • Slang Version 2025.24.3
  • OS Linux 6.18.2-arch2-1 x86_64</issue_description>

<agent_instructions>Please reproduce this issue and then bisect git tree to find out culprit.</agent_instructions>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 2 commits January 14, 2026 12:42
- Created test file to reproduce the SPIR-V validation error
- Confirmed the issue exists in current code
- Identified commit 412d347 as the culprit that introduced the regression
- The commit "Fix nested switch with continue incorrectly collecting parent loop blocks" from Dec 3, 2025 added logic that treats continue blocks as exit points for nested constructs, but this causes SPIR-V to generate invalid structured control flow when a for loop has a continue inside a switch statement

Co-authored-by: jkiviluoto-nv <[email protected]>
…loop

The commit 412d347 added continueBlock to exitBlocks for nested constructs
but forgot to remove it after processing. This caused the continueBlock to
remain in the global exitBlocks set, affecting subsequent region processing
and breaking SPIR-V structured control flow validation.

The fix ensures continueBlock is properly removed from exitBlocks after
processing each region, matching the cleanup pattern for other exit blocks.

Co-authored-by: jkiviluoto-nv <[email protected]>
Copilot AI changed the title [WIP] Fix for loop continue inside switch statement Fix SPIR-V structured control flow violation for continue in switch inside for-loop Jan 14, 2026
Copilot AI requested a review from jkiviluoto-nv January 14, 2026 12:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

For loop continue inside a switch breaks structured control flow

2 participants