-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Description
Description
OpSwitch even as defined with SPV_KHR_maximal_reconvergence, doesn't require converging on switch cases that have fall through.
The only way to get SPIR-V to implement switch statements that converge correctly is with OpBranch instead.
Steps to Reproduce
Given the following HLSL:
RWBuffer<int> value;
[numthreads(4, 1, 1)]
void main(uint3 threadID : SV_DispatchThreadID) {
uint sum = 0;
switch (value[threadID.x]) {
case 0:
sum += WaveActiveSum(1);
default:
sum += WaveActiveSum(10);
break;
}
value[threadID.x] = sum;
}If given the input [ 0, 0, 1, 2], the computed output should be [ 42, 42, 40, 40 ].
Actual Behavior
Even with the KHR maximal reconvergence extension the OpSwitch is not guaranteed to converge the tangles between case 0 and the default case.
However, if instead these were generated as a chain of OpBranch statements, the control flow would converge at each new OpBranch, which would result in the correct tangle grouping.
The HLSL example above does not compile in Clang today due to missing features, a Clang example that is closer to compiling is https://godbolt.org/z/nbhbd8fdK.
Any switch with fallthrough cases that have behavior dependent on participating lanes converging will be undefined behavior if the SPIRV OpSwitch instruction is used, so we should just not generate it ever for HLSL.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status