mirror of
https://github.com/KhronosGroup/SPIRV-Cross.git
synced 2024-11-09 22:00:05 +00:00
Fix cases where SPIR-V conditionally branches to loop headers.
We should check if we are actually branching back to loop header. Fixes some logic when continue_block == loop_header.
This commit is contained in:
parent
92134e410a
commit
ba0ab875c8
@ -10,23 +10,61 @@ layout(binding = 0, std430) buffer SSBO
|
||||
layout(binding = 1, std430) buffer SSBO2
|
||||
{
|
||||
vec4 out_data[];
|
||||
} _125;
|
||||
} _177;
|
||||
|
||||
void main()
|
||||
{
|
||||
uint ident = gl_GlobalInvocationID.x;
|
||||
vec4 idat = _24.in_data[ident];
|
||||
int k = 0;
|
||||
uint i;
|
||||
uint i = 0u;
|
||||
uint i_1;
|
||||
uint j;
|
||||
int l;
|
||||
if ((idat.y == 20.0))
|
||||
{
|
||||
do
|
||||
{
|
||||
k = (k * 2);
|
||||
i = (i + uint(1));
|
||||
} while ((i < ident));
|
||||
}
|
||||
switch (k)
|
||||
{
|
||||
case 10:
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
i = (i + uint(1));
|
||||
if ((i > 10u))
|
||||
{
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
i = (i + 2u);
|
||||
if ((i > 20u))
|
||||
{
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
while ((k < 10))
|
||||
{
|
||||
idat = (idat * 2.0);
|
||||
k = (k + 1);
|
||||
}
|
||||
i = 0u;
|
||||
for (; (i < 16u); i = (i + uint(1)), k = (k + 1))
|
||||
i_1 = 0u;
|
||||
for (; (i_1 < 16u); i_1 = (i_1 + uint(1)), k = (k + 1))
|
||||
{
|
||||
j = 0u;
|
||||
for (; (j < 30u); j = (j + uint(1)))
|
||||
@ -67,6 +105,6 @@ void main()
|
||||
l = (l + 1);
|
||||
continue;
|
||||
}
|
||||
_125.out_data[ident] = idat;
|
||||
_177.out_data[ident] = idat;
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,38 @@ void main()
|
||||
vec4 idat = in_data[ident];
|
||||
|
||||
int k = 0;
|
||||
uint i = 0u;
|
||||
|
||||
if (idat.y == 20.0)
|
||||
{
|
||||
do
|
||||
{
|
||||
k = k * 2;
|
||||
i++;
|
||||
} while (i < ident);
|
||||
}
|
||||
|
||||
switch (k)
|
||||
{
|
||||
case 10:
|
||||
for (;;)
|
||||
{
|
||||
i++;
|
||||
if (i > 10u)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
for (;;)
|
||||
{
|
||||
i += 2u;
|
||||
if (i > 20u)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
while (k < 10)
|
||||
{
|
||||
idat *= 2.0;
|
||||
|
@ -3701,7 +3701,9 @@ void CompilerGLSL::branch(uint32_t from, uint32_t to)
|
||||
flush_phi(from, to);
|
||||
flush_all_active_variables();
|
||||
|
||||
if (loop_block.find(to) != end(loop_block))
|
||||
// This is only a continue if we branch to our loop dominator.
|
||||
if (loop_block.find(to) != end(loop_block) &&
|
||||
get<SPIRBlock>(from).loop_dominator == to)
|
||||
{
|
||||
// This can happen if we had a complex continue block which was emitted.
|
||||
// Once the continue block tries to branch to the loop header, just emit continue;
|
||||
@ -3813,20 +3815,23 @@ void CompilerGLSL::propagate_loop_dominators(const SPIRBlock &block)
|
||||
block.loop_dominator = dominator;
|
||||
};
|
||||
|
||||
// After merging a loop, we inherit the loop dominator always.
|
||||
if (block.merge_block)
|
||||
set_dominator(block.merge_block, block.loop_dominator);
|
||||
|
||||
if (block.true_block)
|
||||
set_dominator(block.true_block, dominator);
|
||||
if (block.false_block)
|
||||
set_dominator(block.false_block, dominator);
|
||||
if (block.next_block)
|
||||
set_dominator(block.next_block, dominator);
|
||||
if (block.continue_block)
|
||||
set_dominator(block.continue_block, dominator);
|
||||
|
||||
for (auto &c : block.cases)
|
||||
set_dominator(c.block, dominator);
|
||||
|
||||
// After merging a loop, we inherit the loop dominator always.
|
||||
if (block.merge_block)
|
||||
set_dominator(block.merge_block, block.loop_dominator);
|
||||
// In older glslang output continue_block can be == loop header.
|
||||
if (block.continue_block && block.continue_block != block.self)
|
||||
set_dominator(block.continue_block, dominator);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user