-
Notifications
You must be signed in to change notification settings - Fork 248
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
Question: why OpSelectionMerge and OpLoopMerge are separate instructions? #147
Comments
Here's my theory that so far fits all the SPIR-V code I saw from the Khronos Group and other vendors:
|
Correct me if I'm wrong. |
Can you give an example of an implicit (undeclared) merge block? We don't need merge instructions for branches that are reconverging the control flow, just for those that are introducing new nested divergence. |
A merge block is always present, it's that
makes OpSelectionMerge implicit (undeclared) sometimes. I hope only for reconverging the control flow.
Why divergence nests? |
Specifically,
Why OpSelectionMerge needs to be issued in a OpLoopMerge block that is already divergent? |
For example: #version 450
layout(location = 0) in vec4 color1;
layout(location = 1) in vec4 multiplier;
layout(location = 2) noperspective in vec4 color2;
layout(location = 0) out vec4 color;
struct S {
bool b;
vec4 v[5];
int i;
};
layout(binding = 0) uniform blockName {
S s;
bool cond;
};
void main()
{
vec4 scale = vec4(1.0, 1.0, 2.0, 1.0);
for (int i = 0; i < 4; ++i) {
if (cond)
color *= color1 + s.v[2];
else
color *= sqrt(color2) * scale;
color *= multiplier;
}
}
Why do you need to issue |
The rules nest. Strip away the loop, and that's the convergence of the divergence that occurred. Not ignoring the loop, it's not a full convergence, but it's still a local convergence, rather than a further divergence. |
I see, so basically SPIR-V is always about explicitly specified by the user divergence and convergence and you guys don't want to deal with cfg analysis and automatic structurization like in DXIL? |
Because if SPIR-V code transform tools are allowed to insert new merge instructions, then you can strip that loop and insert |
SPIR-V for graphics explicitly declares its structured control flow. CFG analysis can be done to verify what was declared, but complex inference is not required. It's a common theme in SPIR-V: Rather than infer (e.g., result types), declare and verify, because in its full generality, verification of a statement is simpler than inference of the statement. |
I see. Thank you for answers, John! The issue can be closed for now. |
If the idea behind
OpSelectionMerge
andOpLoopMerge
is that threads should know when they should diverge and converge, why have 2 separate instructions for conditional statements and loops? The fact that there are 2 instructions gives rise to many corner case questions, questions such as "should a OpLoopMerge block have OpSelectionMerge blocks within itself or not" (SPIR-V documentation example says no, while I sometimes see SPIR-V code in the wild that says yes). I see driver programmers from a big IHV hit these corner cases and complain about it on the Internet in the year of 2019, 5 years after the release of the spec, this is not normal, there are Android phones out there with broken SPIR-V compilers because of that, and many more will come if someone won't clarify all of this in detail.The text was updated successfully, but these errors were encountered: