Support initializers on StorageClassOutput.
diff --git a/reference/opt/shaders-hlsl/asm/frag/storage-class-output-initializer.asm.frag b/reference/opt/shaders-hlsl/asm/frag/storage-class-output-initializer.asm.frag
new file mode 100644
index 0000000..1905b5e
--- /dev/null
+++ b/reference/opt/shaders-hlsl/asm/frag/storage-class-output-initializer.asm.frag
@@ -0,0 +1,23 @@
+static const float4 _20[2] = { float4(1.0f, 2.0f, 3.0f, 4.0f), 10.0f.xxxx };
+
+static float4 FragColors[2] = _20;
+static float4 FragColor = 5.0f.xxxx;
+
+struct SPIRV_Cross_Output
+{
+    float4 FragColors[2] : SV_Target0;
+    float4 FragColor : SV_Target2;
+};
+
+void frag_main()
+{
+}
+
+SPIRV_Cross_Output main()
+{
+    frag_main();
+    SPIRV_Cross_Output stage_output;
+    stage_output.FragColors = FragColors;
+    stage_output.FragColor = FragColor;
+    return stage_output;
+}
diff --git a/reference/opt/shaders-msl/asm/frag/storage-class-output-initializer.asm.frag b/reference/opt/shaders-msl/asm/frag/storage-class-output-initializer.asm.frag
new file mode 100644
index 0000000..1bafc69
--- /dev/null
+++ b/reference/opt/shaders-msl/asm/frag/storage-class-output-initializer.asm.frag
@@ -0,0 +1,24 @@
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+constant float4 _20[2] = { float4(1.0, 2.0, 3.0, 4.0), float4(10.0) };
+
+struct main0_out
+{
+    float4 FragColors_0 [[color(0)]];
+    float4 FragColors_1 [[color(1)]];
+    float4 FragColor [[color(2)]];
+};
+
+fragment main0_out main0()
+{
+    main0_out out = {};
+    float4 FragColors[2] = { float4(1.0, 2.0, 3.0, 4.0), float4(10.0) };
+    out.FragColor = float4(5.0);
+    out.FragColors_0 = FragColors[0];
+    out.FragColors_1 = FragColors[1];
+    return out;
+}
+
diff --git a/reference/opt/shaders/asm/frag/storage-class-output-initializer.asm.frag b/reference/opt/shaders/asm/frag/storage-class-output-initializer.asm.frag
new file mode 100644
index 0000000..2293587
--- /dev/null
+++ b/reference/opt/shaders/asm/frag/storage-class-output-initializer.asm.frag
@@ -0,0 +1,11 @@
+#version 450
+
+layout(location = 0) out vec4 FragColors[2];
+layout(location = 2) out vec4 FragColor;
+
+void main()
+{
+    FragColors = vec4[](vec4(1.0, 2.0, 3.0, 4.0), vec4(10.0));
+    FragColor = vec4(5.0);
+}
+
diff --git a/reference/shaders-hlsl/asm/frag/storage-class-output-initializer.asm.frag b/reference/shaders-hlsl/asm/frag/storage-class-output-initializer.asm.frag
new file mode 100644
index 0000000..1905b5e
--- /dev/null
+++ b/reference/shaders-hlsl/asm/frag/storage-class-output-initializer.asm.frag
@@ -0,0 +1,23 @@
+static const float4 _20[2] = { float4(1.0f, 2.0f, 3.0f, 4.0f), 10.0f.xxxx };
+
+static float4 FragColors[2] = _20;
+static float4 FragColor = 5.0f.xxxx;
+
+struct SPIRV_Cross_Output
+{
+    float4 FragColors[2] : SV_Target0;
+    float4 FragColor : SV_Target2;
+};
+
+void frag_main()
+{
+}
+
+SPIRV_Cross_Output main()
+{
+    frag_main();
+    SPIRV_Cross_Output stage_output;
+    stage_output.FragColors = FragColors;
+    stage_output.FragColor = FragColor;
+    return stage_output;
+}
diff --git a/reference/shaders-msl/asm/frag/storage-class-output-initializer.asm.frag b/reference/shaders-msl/asm/frag/storage-class-output-initializer.asm.frag
new file mode 100644
index 0000000..1bafc69
--- /dev/null
+++ b/reference/shaders-msl/asm/frag/storage-class-output-initializer.asm.frag
@@ -0,0 +1,24 @@
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+constant float4 _20[2] = { float4(1.0, 2.0, 3.0, 4.0), float4(10.0) };
+
+struct main0_out
+{
+    float4 FragColors_0 [[color(0)]];
+    float4 FragColors_1 [[color(1)]];
+    float4 FragColor [[color(2)]];
+};
+
+fragment main0_out main0()
+{
+    main0_out out = {};
+    float4 FragColors[2] = { float4(1.0, 2.0, 3.0, 4.0), float4(10.0) };
+    out.FragColor = float4(5.0);
+    out.FragColors_0 = FragColors[0];
+    out.FragColors_1 = FragColors[1];
+    return out;
+}
+
diff --git a/reference/shaders/asm/frag/storage-class-output-initializer.asm.frag b/reference/shaders/asm/frag/storage-class-output-initializer.asm.frag
new file mode 100644
index 0000000..2293587
--- /dev/null
+++ b/reference/shaders/asm/frag/storage-class-output-initializer.asm.frag
@@ -0,0 +1,11 @@
+#version 450
+
+layout(location = 0) out vec4 FragColors[2];
+layout(location = 2) out vec4 FragColor;
+
+void main()
+{
+    FragColors = vec4[](vec4(1.0, 2.0, 3.0, 4.0), vec4(10.0));
+    FragColor = vec4(5.0);
+}
+
diff --git a/shaders-hlsl/asm/frag/storage-class-output-initializer.asm.frag b/shaders-hlsl/asm/frag/storage-class-output-initializer.asm.frag
new file mode 100644
index 0000000..7763b7c
--- /dev/null
+++ b/shaders-hlsl/asm/frag/storage-class-output-initializer.asm.frag
@@ -0,0 +1,41 @@
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 25
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %main "main" %FragColors %FragColor
+               OpExecutionMode %main OriginUpperLeft
+               OpSource GLSL 450
+               OpName %main "main"
+               OpName %FragColors "FragColors"
+               OpName %FragColor "FragColor"
+               OpDecorate %FragColors Location 0
+               OpDecorate %FragColor Location 2
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+       %uint = OpTypeInt 32 0
+     %uint_2 = OpConstant %uint 2
+%_arr_v4float_uint_2 = OpTypeArray %v4float %uint_2
+%_ptr_Output__arr_v4float_uint_2 = OpTypePointer Output %_arr_v4float_uint_2
+    %float_1 = OpConstant %float 1
+    %float_2 = OpConstant %float 2
+    %float_3 = OpConstant %float 3
+    %float_4 = OpConstant %float 4
+         %17 = OpConstantComposite %v4float %float_1 %float_2 %float_3 %float_4
+   %float_10 = OpConstant %float 10
+         %19 = OpConstantComposite %v4float %float_10 %float_10 %float_10 %float_10
+         %20 = OpConstantComposite %_arr_v4float_uint_2 %17 %19
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+    %float_5 = OpConstant %float 5
+         %24 = OpConstantComposite %v4float %float_5 %float_5 %float_5 %float_5
+ %FragColors = OpVariable %_ptr_Output__arr_v4float_uint_2 Output %20
+  %FragColor = OpVariable %_ptr_Output_v4float Output %24
+       %main = OpFunction %void None %3
+          %5 = OpLabel
+               OpReturn
+               OpFunctionEnd
diff --git a/shaders-msl/asm/frag/storage-class-output-initializer.asm.frag b/shaders-msl/asm/frag/storage-class-output-initializer.asm.frag
new file mode 100644
index 0000000..7763b7c
--- /dev/null
+++ b/shaders-msl/asm/frag/storage-class-output-initializer.asm.frag
@@ -0,0 +1,41 @@
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 25
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %main "main" %FragColors %FragColor
+               OpExecutionMode %main OriginUpperLeft
+               OpSource GLSL 450
+               OpName %main "main"
+               OpName %FragColors "FragColors"
+               OpName %FragColor "FragColor"
+               OpDecorate %FragColors Location 0
+               OpDecorate %FragColor Location 2
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+       %uint = OpTypeInt 32 0
+     %uint_2 = OpConstant %uint 2
+%_arr_v4float_uint_2 = OpTypeArray %v4float %uint_2
+%_ptr_Output__arr_v4float_uint_2 = OpTypePointer Output %_arr_v4float_uint_2
+    %float_1 = OpConstant %float 1
+    %float_2 = OpConstant %float 2
+    %float_3 = OpConstant %float 3
+    %float_4 = OpConstant %float 4
+         %17 = OpConstantComposite %v4float %float_1 %float_2 %float_3 %float_4
+   %float_10 = OpConstant %float 10
+         %19 = OpConstantComposite %v4float %float_10 %float_10 %float_10 %float_10
+         %20 = OpConstantComposite %_arr_v4float_uint_2 %17 %19
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+    %float_5 = OpConstant %float 5
+         %24 = OpConstantComposite %v4float %float_5 %float_5 %float_5 %float_5
+ %FragColors = OpVariable %_ptr_Output__arr_v4float_uint_2 Output %20
+  %FragColor = OpVariable %_ptr_Output_v4float Output %24
+       %main = OpFunction %void None %3
+          %5 = OpLabel
+               OpReturn
+               OpFunctionEnd
diff --git a/shaders/asm/frag/storage-class-output-initializer.asm.frag b/shaders/asm/frag/storage-class-output-initializer.asm.frag
new file mode 100644
index 0000000..7763b7c
--- /dev/null
+++ b/shaders/asm/frag/storage-class-output-initializer.asm.frag
@@ -0,0 +1,41 @@
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 25
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %main "main" %FragColors %FragColor
+               OpExecutionMode %main OriginUpperLeft
+               OpSource GLSL 450
+               OpName %main "main"
+               OpName %FragColors "FragColors"
+               OpName %FragColor "FragColor"
+               OpDecorate %FragColors Location 0
+               OpDecorate %FragColor Location 2
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+       %uint = OpTypeInt 32 0
+     %uint_2 = OpConstant %uint 2
+%_arr_v4float_uint_2 = OpTypeArray %v4float %uint_2
+%_ptr_Output__arr_v4float_uint_2 = OpTypePointer Output %_arr_v4float_uint_2
+    %float_1 = OpConstant %float 1
+    %float_2 = OpConstant %float 2
+    %float_3 = OpConstant %float 3
+    %float_4 = OpConstant %float 4
+         %17 = OpConstantComposite %v4float %float_1 %float_2 %float_3 %float_4
+   %float_10 = OpConstant %float 10
+         %19 = OpConstantComposite %v4float %float_10 %float_10 %float_10 %float_10
+         %20 = OpConstantComposite %_arr_v4float_uint_2 %17 %19
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+    %float_5 = OpConstant %float 5
+         %24 = OpConstantComposite %v4float %float_5 %float_5 %float_5 %float_5
+ %FragColors = OpVariable %_ptr_Output__arr_v4float_uint_2 Output %20
+  %FragColor = OpVariable %_ptr_Output_v4float Output %24
+       %main = OpFunction %void None %3
+          %5 = OpLabel
+               OpReturn
+               OpFunctionEnd
diff --git a/spirv_cross.cpp b/spirv_cross.cpp
index ef3ec24..19bac30 100644
--- a/spirv_cross.cpp
+++ b/spirv_cross.cpp
@@ -701,6 +701,12 @@
 	InterfaceVariableAccessHandler handler(*this, variables);
 	traverse_all_reachable_opcodes(get<SPIRFunction>(ir.default_entry_point), handler);
 
+	// Make sure we preserve output variables which are only initialized, but never accessed by any code.
+	ir.for_each_typed_id<SPIRVariable>([&](uint32_t, const SPIRVariable &var) {
+		if (var.storage == StorageClassOutput && var.initializer != 0)
+			variables.insert(var.self);
+	});
+
 	// If we needed to create one, we'll need it.
 	if (dummy_sampler_id)
 		variables.insert(dummy_sampler_id);
diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp
index e4d54e0..a0b826d 100644
--- a/spirv_glsl.cpp
+++ b/spirv_glsl.cpp
@@ -1743,6 +1743,15 @@
 			add_resource_name(var.self);
 			statement(layout_for_variable(var), to_qualifiers_glsl(var.self),
 			          variable_decl(type, to_name(var.self), var.self), ";");
+
+			// If a StorageClassOutput variable has an initializer, we need to initialize it in main().
+			if (var.storage == StorageClassOutput && var.initializer)
+			{
+				auto &entry_func = this->get<SPIRFunction>(ir.default_entry_point);
+				entry_func.fixup_hooks_in.push_back([&]() {
+					statement(to_name(var.self), " = ", to_expression(var.initializer), ";");
+				});
+			}
 		}
 	}
 }
diff --git a/spirv_msl.cpp b/spirv_msl.cpp
index 7f2d3c6..fd90160 100644
--- a/spirv_msl.cpp
+++ b/spirv_msl.cpp
@@ -851,10 +851,10 @@
 
 	// Update the original variable reference to include the structure reference
 	string qual_var_name = ib_var_ref + "." + mbr_name;
+	auto &entry_func = get<SPIRFunction>(ir.default_entry_point);
 
 	if (padded_output)
 	{
-		auto &entry_func = get<SPIRFunction>(ir.default_entry_point);
 		entry_func.add_local_variable(var.self);
 		vars_needing_early_declaration.push_back(var.self);
 
@@ -866,6 +866,13 @@
 	else
 		ir.meta[var.self].decoration.qualified_alias = qual_var_name;
 
+	if (var.storage == StorageClassOutput && var.initializer != 0)
+	{
+		entry_func.fixup_hooks_in.push_back([=, &var]() {
+			statement(qual_var_name, " = ", to_expression(var.initializer), ";");
+		});
+	}
+
 	// Copy the variable location from the original variable to the member
 	if (get_decoration_bitset(var.self).get(DecorationLocation))
 	{
@@ -3383,10 +3390,13 @@
 		for (auto var_id : vars_needing_early_declaration)
 		{
 			auto &ed_var = get<SPIRVariable>(var_id);
-			if (!ed_var.initializer)
-				ed_var.initializer = ir.increase_bound_by(1);
+			uint32_t &initializer = ed_var.initializer;
+			if (!initializer)
+				initializer = ir.increase_bound_by(1);
 
-			set<SPIRExpression>(ed_var.initializer, "{}", ed_var.basetype, true);
+			// Do not override proper initializers.
+			if (ir.ids[initializer].get_type() == TypeNone || ir.ids[initializer].get_type() == TypeExpression)
+				set<SPIRExpression>(ed_var.initializer, "{}", ed_var.basetype, true);
 		}
 	}