mirror of
https://github.com/KhronosGroup/SPIRV-Cross.git
synced 2024-11-15 00:11:06 +00:00
Do not force temporary unless continue-only for loop dominates.
We would force temporaries in unexpected places, causing assertions to throw if access chains were consumed in such loops.
This commit is contained in:
parent
301eab1b7a
commit
d620f1dd26
@ -14,14 +14,12 @@ struct SPIRV_Cross_Output
|
||||
#line 8 "test.frag"
|
||||
void frag_main()
|
||||
{
|
||||
float _80;
|
||||
#line 8 "test.frag"
|
||||
FragColor = 1.0f;
|
||||
#line 9 "test.frag"
|
||||
FragColor = 2.0f;
|
||||
#line 10 "test.frag"
|
||||
_80 = vColor;
|
||||
if (_80 < 0.0f)
|
||||
if (vColor < 0.0f)
|
||||
{
|
||||
#line 12 "test.frag"
|
||||
FragColor = 3.0f;
|
||||
@ -31,16 +29,16 @@ void frag_main()
|
||||
#line 16 "test.frag"
|
||||
FragColor = 4.0f;
|
||||
}
|
||||
for (int _126 = 0; float(_126) < (40.0f + _80); )
|
||||
for (int _126 = 0; float(_126) < (40.0f + vColor); )
|
||||
{
|
||||
#line 21 "test.frag"
|
||||
FragColor += 0.20000000298023223876953125f;
|
||||
#line 22 "test.frag"
|
||||
FragColor += 0.300000011920928955078125f;
|
||||
_126 += (int(_80) + 5);
|
||||
_126 += (int(vColor) + 5);
|
||||
continue;
|
||||
}
|
||||
switch (int(_80))
|
||||
switch (int(vColor))
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
@ -66,7 +64,7 @@ void frag_main()
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
FragColor += (10.0f + _80);
|
||||
FragColor += (10.0f + vColor);
|
||||
#line 43 "test.frag"
|
||||
if (FragColor < 100.0f)
|
||||
{
|
||||
|
@ -17,14 +17,12 @@ struct main0_in
|
||||
fragment main0_out main0(main0_in in [[stage_in]])
|
||||
{
|
||||
main0_out out = {};
|
||||
float _80;
|
||||
#line 8 "test.frag"
|
||||
out.FragColor = 1.0;
|
||||
#line 9 "test.frag"
|
||||
out.FragColor = 2.0;
|
||||
#line 10 "test.frag"
|
||||
_80 = in.vColor;
|
||||
if (_80 < 0.0)
|
||||
if (in.vColor < 0.0)
|
||||
{
|
||||
#line 12 "test.frag"
|
||||
out.FragColor = 3.0;
|
||||
@ -34,16 +32,16 @@ fragment main0_out main0(main0_in in [[stage_in]])
|
||||
#line 16 "test.frag"
|
||||
out.FragColor = 4.0;
|
||||
}
|
||||
for (int _126 = 0; float(_126) < (40.0 + _80); )
|
||||
for (int _126 = 0; float(_126) < (40.0 + in.vColor); )
|
||||
{
|
||||
#line 21 "test.frag"
|
||||
out.FragColor += 0.20000000298023223876953125;
|
||||
#line 22 "test.frag"
|
||||
out.FragColor += 0.300000011920928955078125;
|
||||
_126 += (int(_80) + 5);
|
||||
_126 += (int(in.vColor) + 5);
|
||||
continue;
|
||||
}
|
||||
switch (int(_80))
|
||||
switch (int(in.vColor))
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
@ -69,7 +67,7 @@ fragment main0_out main0(main0_in in [[stage_in]])
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
out.FragColor += (10.0 + _80);
|
||||
out.FragColor += (10.0 + in.vColor);
|
||||
#line 43 "test.frag"
|
||||
if (out.FragColor < 100.0)
|
||||
{
|
||||
|
@ -7,14 +7,12 @@ layout(location = 0) in float vColor;
|
||||
#line 8 "test.frag"
|
||||
void main()
|
||||
{
|
||||
float _80;
|
||||
#line 8 "test.frag"
|
||||
FragColor = 1.0;
|
||||
#line 9 "test.frag"
|
||||
FragColor = 2.0;
|
||||
#line 10 "test.frag"
|
||||
_80 = vColor;
|
||||
if (_80 < 0.0)
|
||||
if (vColor < 0.0)
|
||||
{
|
||||
#line 12 "test.frag"
|
||||
FragColor = 3.0;
|
||||
@ -24,16 +22,16 @@ void main()
|
||||
#line 16 "test.frag"
|
||||
FragColor = 4.0;
|
||||
}
|
||||
for (int _126 = 0; float(_126) < (40.0 + _80); )
|
||||
for (int _126 = 0; float(_126) < (40.0 + vColor); )
|
||||
{
|
||||
#line 21 "test.frag"
|
||||
FragColor += 0.20000000298023223876953125;
|
||||
#line 22 "test.frag"
|
||||
FragColor += 0.300000011920928955078125;
|
||||
_126 += (int(_80) + 5);
|
||||
_126 += (int(vColor) + 5);
|
||||
continue;
|
||||
}
|
||||
switch (int(_80))
|
||||
switch (int(vColor))
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
@ -59,7 +57,7 @@ void main()
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
FragColor += (10.0 + _80);
|
||||
FragColor += (10.0 + vColor);
|
||||
#line 43 "test.frag"
|
||||
if (FragColor < 100.0)
|
||||
{
|
||||
|
@ -3294,10 +3294,11 @@ void Compiler::analyze_variable_scope(SPIRFunction &entry, AnalyzeVariableScopeA
|
||||
{
|
||||
builder.add_block(block);
|
||||
|
||||
// If a temporary is used in more than one block, we might have to lift continue block
|
||||
// access up to loop header like we did for variables.
|
||||
if (blocks.size() != 1 && is_continue(block))
|
||||
{
|
||||
// The risk here is that inner loop can dominate the continue block.
|
||||
// Any temporary we access in the continue block must be declared before the loop.
|
||||
// This is moot for complex loops however.
|
||||
auto &loop_header_block = get<SPIRBlock>(ir.continue_block_to_loop_header[block]);
|
||||
assert(loop_header_block.merge == SPIRBlock::MergeLoop);
|
||||
|
||||
@ -3305,14 +3306,17 @@ void Compiler::analyze_variable_scope(SPIRFunction &entry, AnalyzeVariableScopeA
|
||||
if (!loop_header_block.complex_continue)
|
||||
builder.add_block(loop_header_block.self);
|
||||
}
|
||||
else if (blocks.size() != 1 && is_single_block_loop(block))
|
||||
{
|
||||
// Awkward case, because the loop header is also the continue block.
|
||||
force_temporary = true;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t dominating_block = builder.get_dominator();
|
||||
|
||||
if (blocks.size() != 1 && is_single_block_loop(dominating_block))
|
||||
{
|
||||
// Awkward case, because the loop header is also the continue block,
|
||||
// so hoisting to loop header does not help.
|
||||
force_temporary = true;
|
||||
}
|
||||
|
||||
if (dominating_block)
|
||||
{
|
||||
// If we touch a variable in the dominating block, this is the expected setup.
|
||||
|
Loading…
Reference in New Issue
Block a user