You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Jan 29, 2025. It is now read-only.
When talking with @jimblandy about naga's expression/statement representation, I wondered how naga handles SPIR-V control flow that does something like a multi-level break.
I remembered that spirv-opt emits a strange code pattern when inlining a function with a return statement nested inside control flow: it wraps the inlined function in a switch (0) { default: { the function's code } }, and any return statement of the inlined function branches to the end of the switch statement. SPIR-V allows skipping over merge blocks (pretty insane if you ask me, but that's how it is), kinda like a multi-level break, so this is valid.
So, I wrote up a GLSL example with a return statement in some control flow in an inlined function, threw it through glslang and spirv-opt, took the spir-v binary and pushed it through naga with my silly wgpu test app, and naga panicked.
thread 'main' panicked at 'internal error: entered unreachable code: Expression [15] is already cached!', C:\Users\khype\.cargo\registry\src\github.com-1ecc6299db9ec823\naga-0.4.2\src\back\spv\writer.rs:2380:9
I'm on Windows, if that's relevant. The GLSL and SPIR-V shader binary can be played with on shader-playground, although I've included both below for convenience. The SPIR-V binary passes spirv-val. (The shader-playground link does have a "download binary" button, though, so you don't have to go through the trouble of assembling it)
When talking with @jimblandy about naga's expression/statement representation, I wondered how naga handles SPIR-V control flow that does something like a multi-level break.
I remembered that spirv-opt emits a strange code pattern when inlining a function with a return statement nested inside control flow: it wraps the inlined function in a
switch (0) { default: { the function's code } }
, and any return statement of the inlined function branches to the end of the switch statement. SPIR-V allows skipping over merge blocks (pretty insane if you ask me, but that's how it is), kinda like a multi-level break, so this is valid.So, I wrote up a GLSL example with a return statement in some control flow in an inlined function, threw it through glslang and spirv-opt, took the spir-v binary and pushed it through naga with my silly wgpu test app, and naga panicked.
I'm on Windows, if that's relevant. The GLSL and SPIR-V shader binary can be played with on shader-playground, although I've included both below for convenience. The SPIR-V binary passes spirv-val. (The shader-playground link does have a "download binary" button, though, so you don't have to go through the trouble of assembling it)
Disassembled SPIR-V, click to expand
The text was updated successfully, but these errors were encountered: