Fall back to complex loop if non-trivial continue block is found.

There is a case where we can deduce a for/while loop, but the continue
block is actually very painful to deal with, so handle that case as
well. Removes an exceptional case.
This commit is contained in:
Hans-Kristian Arntzen 2019-07-08 11:48:44 +02:00
parent 13378ad1ac
commit 50342966c0
10 changed files with 224 additions and 2 deletions

View File

@ -0,0 +1,25 @@
static float4 FragColor;
struct SPIRV_Cross_Output
{
float4 FragColor : SV_Target0;
};
void frag_main()
{
FragColor = 0.0f.xxxx;
for (int _43 = 0; _43 < 3; )
{
FragColor[_43] += float(_43);
_43++;
continue;
}
}
SPIRV_Cross_Output main()
{
frag_main();
SPIRV_Cross_Output stage_output;
stage_output.FragColor = FragColor;
return stage_output;
}

View File

@ -0,0 +1,23 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float4 FragColor [[color(0)]];
};
fragment main0_out main0()
{
main0_out out = {};
out.FragColor = float4(0.0);
for (int _43 = 0; _43 < 3; )
{
out.FragColor[_43] += float(_43);
_43++;
continue;
}
return out;
}

View File

@ -0,0 +1,15 @@
#version 450
layout(location = 0) out vec4 FragColor;
void main()
{
FragColor = vec4(0.0);
for (int _43 = 0; _43 < 3; )
{
FragColor[_43] += float(_43);
_43++;
continue;
}
}

View File

@ -0,0 +1,44 @@
static float4 FragColor;
struct SPIRV_Cross_Output
{
float4 FragColor : SV_Target0;
};
void frag_main()
{
FragColor = 0.0f.xxxx;
int i = 0;
int _36;
for (;;)
{
if (i < 3)
{
int a = i;
FragColor[a] += float(i);
if (false)
{
_36 = 1;
}
else
{
int _41 = i;
i = _41 + 1;
_36 = _41;
}
continue;
}
else
{
break;
}
}
}
SPIRV_Cross_Output main()
{
frag_main();
SPIRV_Cross_Output stage_output;
stage_output.FragColor = FragColor;
return stage_output;
}

View File

@ -0,0 +1,42 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float4 FragColor [[color(0)]];
};
fragment main0_out main0()
{
main0_out out = {};
out.FragColor = float4(0.0);
int i = 0;
int _36;
for (;;)
{
if (i < 3)
{
int a = i;
out.FragColor[a] += float(i);
if (false)
{
_36 = 1;
}
else
{
int _41 = i;
i = _41 + 1;
_36 = _41;
}
continue;
}
else
{
break;
}
}
return out;
}

View File

@ -0,0 +1,34 @@
#version 450
layout(location = 0) out vec4 FragColor;
void main()
{
FragColor = vec4(0.0);
int i = 0;
int _36;
for (;;)
{
if (i < 3)
{
int a = i;
FragColor[a] += float(i);
if (false)
{
_36 = 1;
}
else
{
int _41 = i;
i = _41 + 1;
_36 = _41;
}
continue;
}
else
{
break;
}
}
}

View File

@ -0,0 +1,11 @@
#version 450
layout(location = 0) out vec4 FragColor;
void main()
{
FragColor = vec4(0.0);
for (int i = 0; i < 3; (0 > 1) ? 1 : i ++)
{
int a = i;
FragColor[a] += float(i);
}
}

View File

@ -0,0 +1,11 @@
#version 450
layout(location = 0) out vec4 FragColor;
void main()
{
FragColor = vec4(0.0);
for (int i = 0; i < 3; (0 > 1) ? 1 : i ++)
{
int a = i;
FragColor[a] += float(i);
}
}

View File

@ -0,0 +1,11 @@
#version 450
layout(location = 0) out vec4 FragColor;
void main()
{
FragColor = vec4(0.0);
for (int i = 0; i < 3; (0 > 1) ? 1 : i ++)
{
int a = i;
FragColor[a] += float(i);
}
}

View File

@ -11226,7 +11226,10 @@ bool CompilerGLSL::attempt_emit_loop_header(SPIRBlock &block, SPIRBlock::Method
}
default:
SPIRV_CROSS_THROW("For/while loop detected, but need while/for loop semantics.");
block.disable_block_optimization = true;
force_recompile();
begin_scope(); // We'll see an end_scope() later.
return false;
}
begin_scope();
@ -11300,7 +11303,10 @@ bool CompilerGLSL::attempt_emit_loop_header(SPIRBlock &block, SPIRBlock::Method
}
default:
SPIRV_CROSS_THROW("For/while loop detected, but need while/for loop semantics.");
block.disable_block_optimization = true;
force_recompile();
begin_scope(); // We'll see an end_scope() later.
return false;
}
begin_scope();