Merge pull request #1043 from KhronosGroup/fix-1042

Fix declaration of loop variables with a Phi helper copy.
This commit is contained in:
Hans-Kristian Arntzen 2019-06-25 12:08:41 +02:00 committed by GitHub
commit 4bbf343a7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 137 additions and 8 deletions

View File

@ -0,0 +1,25 @@
#version 450
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
layout(binding = 1, rgba32f) uniform writeonly image2D outImageTexture;
void main()
{
int _30;
_30 = 7;
int _27_copy;
for (int _27 = 7; _27 >= 0; _27_copy = _27, _27--, _30 = _27_copy)
{
if (5.0 > float(_27))
{
break;
}
else
{
continue;
}
continue;
}
imageStore(outImageTexture, ivec2(gl_GlobalInvocationID.xy), vec4(float(_30 - 1), float(_30), 1.0, 1.0));
}

View File

@ -0,0 +1,25 @@
#version 450
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
layout(binding = 1, rgba32f) uniform writeonly image2D outImageTexture;
void main()
{
int _30;
_30 = 7;
int _27_copy;
for (int _27 = 7; _27 >= 0; _27_copy = _27, _27--, _30 = _27_copy)
{
if (5.0 > float(_27))
{
break;
}
else
{
continue;
}
continue;
}
imageStore(outImageTexture, ivec2(gl_GlobalInvocationID.xy), vec4(float(_30 - 1), float(_30), 1.0, 1.0));
}

View File

@ -0,0 +1,68 @@
; SPIR-V
; Version: 1.0
; Generator: Google spiregg; 0
; Bound: 42
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %cs_test "main" %gl_GlobalInvocationID %gl_LocalInvocationIndex
OpExecutionMode %cs_test LocalSize 8 8 1
OpSource HLSL 600
OpName %type_2d_image "type.2d.image"
OpName %outImageTexture "outImageTexture"
OpName %cs_test "cs_test"
OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
OpDecorate %gl_LocalInvocationIndex BuiltIn LocalInvocationIndex
OpDecorate %outImageTexture DescriptorSet 0
OpDecorate %outImageTexture Binding 1
%float = OpTypeFloat 32
%float_5 = OpConstant %float 5
%float_1 = OpConstant %float 1
%int = OpTypeInt 32 1
%int_7 = OpConstant %int 7
%int_0 = OpConstant %int 0
%int_1 = OpConstant %int 1
%type_2d_image = OpTypeImage %float 2D 2 0 0 2 Rgba32f
%_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image
%uint = OpTypeInt 32 0
%v3uint = OpTypeVector %uint 3
%_ptr_Input_v3uint = OpTypePointer Input %v3uint
%_ptr_Input_uint = OpTypePointer Input %uint
%void = OpTypeVoid
%19 = OpTypeFunction %void
%v2uint = OpTypeVector %uint 2
%v4float = OpTypeVector %float 4
%bool = OpTypeBool
%outImageTexture = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
%gl_LocalInvocationIndex = OpVariable %_ptr_Input_uint Input
%cs_test = OpFunction %void None %19
%23 = OpLabel
%24 = OpLoad %v3uint %gl_GlobalInvocationID
%25 = OpVectorShuffle %v2uint %24 %24 0 1
OpBranch %26
%26 = OpLabel
%27 = OpPhi %int %int_7 %23 %28 %29
%30 = OpPhi %int %int_7 %23 %27 %29
%31 = OpSGreaterThanEqual %bool %27 %int_0
OpLoopMerge %32 %29 None
OpBranchConditional %31 %33 %32
%33 = OpLabel
%34 = OpConvertSToF %float %27
%35 = OpFOrdGreaterThan %bool %float_5 %34
OpSelectionMerge %29 None
OpBranchConditional %35 %36 %29
%36 = OpLabel
OpBranch %32
%29 = OpLabel
%28 = OpISub %int %27 %int_1
OpBranch %26
%32 = OpLabel
%37 = OpISub %int %30 %int_1
%38 = OpConvertSToF %float %37
%39 = OpConvertSToF %float %30
%40 = OpCompositeConstruct %v4float %38 %39 %float_1 %float_1
%41 = OpLoad %type_2d_image %outImageTexture
OpImageWrite %41 %25 %40 None
OpReturn
OpFunctionEnd

View File

@ -7107,18 +7107,23 @@ string CompilerGLSL::variable_decl_function_local(SPIRVariable &var)
return expr; return expr;
} }
void CompilerGLSL::emit_variable_temporary_copies(const SPIRVariable &var)
{
if (var.allocate_temporary_copy)
{
auto &type = get<SPIRType>(var.basetype);
auto &flags = get_decoration_bitset(var.self);
statement(flags_to_qualifiers_glsl(type, flags), variable_decl(type, join("_", var.self, "_copy")), ";");
}
}
void CompilerGLSL::flush_variable_declaration(uint32_t id) void CompilerGLSL::flush_variable_declaration(uint32_t id)
{ {
auto *var = maybe_get<SPIRVariable>(id); auto *var = maybe_get<SPIRVariable>(id);
if (var && var->deferred_declaration) if (var && var->deferred_declaration)
{ {
statement(variable_decl_function_local(*var), ";"); statement(variable_decl_function_local(*var), ";");
if (var->allocate_temporary_copy) emit_variable_temporary_copies(*var);
{
auto &type = get<SPIRType>(var->basetype);
auto &flags = ir.meta[id].decoration.decoration_flags;
statement(flags_to_qualifiers_glsl(type, flags), variable_decl(type, join("_", id, "_copy")), ";");
}
var->deferred_declaration = false; var->deferred_declaration = false;
} }
} }
@ -11325,8 +11330,13 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
continue_type = continue_block_type(get<SPIRBlock>(block.continue_block)); continue_type = continue_block_type(get<SPIRBlock>(block.continue_block));
// If we have loop variables, stop masking out access to the variable now. // If we have loop variables, stop masking out access to the variable now.
for (auto var : block.loop_variables) for (auto var_id : block.loop_variables)
get<SPIRVariable>(var).loop_variable_enable = true; {
auto &var = get<SPIRVariable>(var_id);
var.loop_variable_enable = true;
// We're not going to declare the variable directly, so emit a copy here.
emit_variable_temporary_copies(var);
}
// Remember deferred declaration state. We will restore it before returning. // Remember deferred declaration state. We will restore it before returning.
SmallVector<bool, 64> rearm_dominated_variables(block.dominated_variables.size()); SmallVector<bool, 64> rearm_dominated_variables(block.dominated_variables.size());

View File

@ -432,6 +432,7 @@ protected:
bool flush_phi_required(uint32_t from, uint32_t to); bool flush_phi_required(uint32_t from, uint32_t to);
void flush_variable_declaration(uint32_t id); void flush_variable_declaration(uint32_t id);
void flush_undeclared_variables(SPIRBlock &block); void flush_undeclared_variables(SPIRBlock &block);
void emit_variable_temporary_copies(const SPIRVariable &var);
bool should_dereference(uint32_t id); bool should_dereference(uint32_t id);
bool should_forward(uint32_t id); bool should_forward(uint32_t id);