MSL: Deal correctly with initializers on Private variables.

Do not attempt to defer declaration. It would happen to work in most
cases, but the edge case is where the first thing that happens to a
variable is being OpStore'd into.
This commit is contained in:
Hans-Kristian Arntzen 2020-04-21 11:20:49 +02:00
parent 3fb86e4385
commit f8592ecdfc
4 changed files with 65 additions and 5 deletions

View File

@ -16,7 +16,7 @@ constant uint3 gl_WorkGroupSize [[maybe_unused]] = uint3(_3, 2u, _4);
kernel void main0(device _6& _8 [[buffer(0)]], device _6& _9 [[buffer(1)]], uint3 gl_WorkGroupID [[threadgroup_position_in_grid]])
{
_8._m0[gl_WorkGroupID.x] = _9._m0[gl_WorkGroupID.x] + _8._m0[gl_WorkGroupID.x];
uint3 _23 = gl_WorkGroupSize;
_8._m0[gl_WorkGroupID.x] = _9._m0[gl_WorkGroupID.x] + _8._m0[gl_WorkGroupID.x];
}

View File

@ -0,0 +1,19 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float FragColor [[color(0)]];
};
fragment main0_out main0()
{
main0_out out = {};
float b = 10.0;
b = 20.0;
out.FragColor = b + b;
return out;
}

View File

@ -0,0 +1,32 @@
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 8
; Bound: 17
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %FragColor
OpExecutionMode %main OriginUpperLeft
OpSource GLSL 450
OpName %main "main"
OpName %b "b"
OpName %FragColor "FragColor"
OpDecorate %FragColor Location 0
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%_ptr_Private_float = OpTypePointer Private %float
%float_10 = OpConstant %float 10
%float_20 = OpConstant %float 20
%b = OpVariable %_ptr_Private_float Private %float_10
%_ptr_Output_float = OpTypePointer Output %float
%FragColor = OpVariable %_ptr_Output_float Output
%main = OpFunction %void None %3
%5 = OpLabel
OpStore %b %float_20
%15 = OpLoad %float %b
%16 = OpFAdd %float %15 %15
OpStore %FragColor %16
OpReturn
OpFunctionEnd

View File

@ -11908,10 +11908,19 @@ void CompilerGLSL::emit_function(SPIRFunction &func, const Bitset &return_flags)
// If we don't declare the variable when it is assigned we're forced to go through a helper function
// which copies elements one by one.
add_local_variable_name(var.self);
auto &dominated = entry_block.dominated_variables;
if (find(begin(dominated), end(dominated), var.self) == end(dominated))
entry_block.dominated_variables.push_back(var.self);
var.deferred_declaration = true;
if (var.initializer)
{
statement(variable_decl(var), ";");
var.deferred_declaration = false;
}
else
{
auto &dominated = entry_block.dominated_variables;
if (find(begin(dominated), end(dominated), var.self) == end(dominated))
entry_block.dominated_variables.push_back(var.self);
var.deferred_declaration = true;
}
}
else if (var.storage == StorageClassFunction && var.remapped_variable && var.static_expression)
{