-
Notifications
You must be signed in to change notification settings - Fork 533
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
Inliner: Generates invalid structured control flow when function call is in a single-block loop, and callee has control flow #787
Labels
Comments
Cc @greg-lunarg . Here's a fun one. I can probably hand-code more compact example, but I think you can think about the solution. :-) |
I'm working on a fix. |
First impression: Before inlining, break all single block loops into "canonical" empty header form. |
dneto0
added a commit
to dneto0/SPIRV-Tools
that referenced
this issue
Aug 31, 2017
If the caller block is a single-block loop and inlining will replace the caller block by several blocks, then: - The original OpLoopMerge instruction will end up in the *last* such block. That's the wrong place to put it. - Move it back to the end of the first block. - Update its Continue Target ID to point to the last block We also have to take care of cases where the inlined code begins with a structured header block. In this case we need to ensure the restored OpLoopMerge does not appear in the same block as the merge instruction from the callee's first block. Fixes KhronosGroup#787
dneto0
added a commit
to dneto0/SPIRV-Tools
that referenced
this issue
Sep 1, 2017
If the caller block is a single-block loop and inlining will replace the caller block by several blocks, then: - The original OpLoopMerge instruction will end up in the *last* such block. That's the wrong place to put it. - Move it back to the end of the first block. - Update its Continue Target ID to point to the last block We also have to take care of cases where the inlined code begins with a structured header block. In this case we need to ensure the restored OpLoopMerge does not appear in the same block as the merge instruction from the callee's first block. Fixes KhronosGroup#787
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Here's a somewhat reduced example:
Original OpenCL C source:
Compling with https://github.com/google/clspv we get:
The control flow graph is:
The 'bar' function starts at block with id 27, and has a simple selection structure.
The interesting bit is the loop with a single block with id 42 in the entry point 'foo'.
After inlining, I get this result:
I've attached the SPIR-V:
b.spv.txt
The problem is that the old block 42 has been split with head 42 the callee's body has been inserted as the last part of 42 and with new block 58 and 57. Unfortunately, the OpLoopMerge originally in 42 is kept as the last instruction in block 57, when it really should have been kept as the second last instruction in 42.
Basically, the structured control flow properties are corrupted. The validator catches this, saying:
It detects the back-edge from 57 to 42, and expects the OpLoopMerge to be in block 42. It should be there, but isn't, and so it complains that block 42 is not a loop header. It's right.
The text was updated successfully, but these errors were encountered: