-
Notifications
You must be signed in to change notification settings - Fork 963
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[spv-in] Naga miscompiles SPIR-V with branches that exit more than one level of structured control flow #4449
Comments
I'm guessing they're loop breaks, because of |
Thank you for filing! |
Just FYI, these confusing
are added by I'm encountering this problem with rust-gpu shader that peforms an |
As a temporary workaround, I've written an optimisation pass that removed the redundant branch: https://github.com/expenses/spirv-extra-opt-passes/blob/194f01af2957eab95195021f8e86e1cf5a7f0884/src/lib.rs#L841-L902. It's a bit hacked together and probably won't work outside of very simple cases because I don't correct the new merge block in subsequent |
That SPIR-V validates fine, so we can assume the breaks follow the structured control flow rules, and our front end ought to be handling it. (Naga does not fully validate SPIR-V; that's too big a job.) The The SPIR-V front end records all merge blocks, so it recognizes that the But I think the problem is here, where we try to add the right
(See the docs on A Changing Naga IR to provide "break from innermost loop" would require supporting that IR in all the back ends. I think it would be better for the SPIR-V front end to introduce a bool variable and do a conditional break after the switch. cc @JCapucho |
I agree with you in everything, this will probably need us to maintain depth information for continues and breaks (something that we discussed initially but didn't implement because it didn't seem necessary, didn't age well), the hardest part will be adding the I'm not planning to work on this issue in the near future but if anyone wants guidance I'm available. |
Note that since we last looked at this, the section on "Structured control flow" in the SPIR-V section has been completely rewritten. Double-check me on this, but I think the new language says that, although it is okay to break out of a loop from within enclosed selection and switch constructs, you can't break out of more than one level of loop. This is equivalent to having two kinds of I'm not sure that really simplifies anything. The back ends other than SPIR-V still can't express this, so I think it still makes sense to keep it out of Naga IR, and make the front end responsible for injecting the bools and branches. |
I agree, but also I would go further and say that conflating the two is a syntactic confusion comparable to conflating
I agree, though for a somewhat different reason(actually "structured" control-flow disallows early exits of any kind and is much closer to e.g. SESE control-flow graphs, or functional I may want to take this on, if I can confirm |
Managed to make a pure Naga+
It's pretty clear that the WGSL post- |
Using rust-gpu, this shader:
Notice that this is the core of what a for loop generated
The downloadable SPIRV and disassembly
A built version of the shader is here: simplest_shader.zip)
And the dissasembly is:
Loops infinitely in the
naga
output, but not when using the passthrough/'raw spirv' feature. Notice that this is the core of aAccording to spirv-cross, the equivalent GLSL is:
Notice the
_53_ladder_break
. Naga however generates:where the innermost loop does not have an exit condition.
The merge block of the innermost switch is the branch when the discriminant is zero (the
Some
case),In every other case, the function exits, eventually.
That is, effectively we have
But naga is confusing the
continue
with another break.It's also possible that rust-gpu's codegen is wrong here. In:
the multiple jumps to
%48
seem suspect to me, since that is not the merge block.The text was updated successfully, but these errors were encountered: