Merge pull request #1102 from KhronosGroup/fix-1096
MSL: Deal with Modf/Frexp where output is access chain to scalar.
diff --git a/reference/opt/shaders-hlsl/asm/frag/line-directive.line.asm.frag b/reference/opt/shaders-hlsl/asm/frag/line-directive.line.asm.frag
index b596a84..93bb69e 100644
--- a/reference/opt/shaders-hlsl/asm/frag/line-directive.line.asm.frag
+++ b/reference/opt/shaders-hlsl/asm/frag/line-directive.line.asm.frag
@@ -14,14 +14,12 @@
#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 @@
#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 @@
}
for (;;)
{
- FragColor += (10.0f + _80);
+ FragColor += (10.0f + vColor);
#line 43 "test.frag"
if (FragColor < 100.0f)
{
diff --git a/reference/opt/shaders-msl/asm/frag/line-directive.line.asm.frag b/reference/opt/shaders-msl/asm/frag/line-directive.line.asm.frag
index 30018aa..0d9666d 100644
--- a/reference/opt/shaders-msl/asm/frag/line-directive.line.asm.frag
+++ b/reference/opt/shaders-msl/asm/frag/line-directive.line.asm.frag
@@ -17,14 +17,12 @@
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 @@
#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 @@
}
for (;;)
{
- out.FragColor += (10.0 + _80);
+ out.FragColor += (10.0 + in.vColor);
#line 43 "test.frag"
if (out.FragColor < 100.0)
{
diff --git a/reference/opt/shaders/asm/frag/line-directive.line.asm.frag b/reference/opt/shaders/asm/frag/line-directive.line.asm.frag
index 30be934..74eb62b 100644
--- a/reference/opt/shaders/asm/frag/line-directive.line.asm.frag
+++ b/reference/opt/shaders/asm/frag/line-directive.line.asm.frag
@@ -7,14 +7,12 @@
#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 @@
#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 @@
}
for (;;)
{
- FragColor += (10.0 + _80);
+ FragColor += (10.0 + vColor);
#line 43 "test.frag"
if (FragColor < 100.0)
{
diff --git a/spirv_cross.cpp b/spirv_cross.cpp
index c29f168..3a9670e 100644
--- a/spirv_cross.cpp
+++ b/spirv_cross.cpp
@@ -3294,10 +3294,11 @@
{
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 @@
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.