Closed paulthomson closed 5 years ago
In this case, we are merging the continue block for the loop with the block that contains the continue. This moves the continue into the merge construct for the outer selection construct.
I'm not sure what the best fix is yet.
This is a bigger problem than just continue targets. In general, the algorithm will move the successor block up into the predecessor. This can move code that was outside of a construct into a construct. I'll attach an example where a regular block is merged with a merge block causing what I believe to be a problem.
Right now I believe the best way to fix this is to move code from the predecessor into the successor when merging blocks. I need to double check what is valid and what is not.
What pass is generating the bad code?
It is in the merge-blocks pass. Alan says the code in 2743.zip is not invalid, so this problem is really just about continues. I cannot convince myself that we can move the code into the predecessor in all cases. I suggest we simply avoid merging when the successor is a continue construct when the predecessor is in a nested construct.
Correction. We now believe the original problem is a bug in the validator. The continue block should not be considered part of the selection construct. This means the branch to the header is not an exit from the selection construct, but the branch to the continue block. It is a legal exit. Passing to @alan-baker.
bug_report.zip
Issue found using GraphicsFuzz.
Tool versions:
To reproduce:
glslangValidator -V shader.frag -o shader.frag.spv
spirv-opt shader.frag.spv -o temp.spv --validate-after-all -O
The following shader files are included in the attached archive, some of which are also shown inline below:
0_glsl/shader.frag:
1_spirv_asm/shader.frag.asm: