[Spirv] Set up internal push constants

Use the PreparePushConstants transform to create entries for all
provided offsets.

Bug: 366291600
Change-Id: Icd4ea4ee31dbfb1df29d1495480948641c61fff9
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/220155
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: Shaobo Yan <shaoboyan@microsoft.com>
diff --git a/src/tint/cmd/tint/main.cc b/src/tint/cmd/tint/main.cc
index c8ecc9c..3c78b6f 100644
--- a/src/tint/cmd/tint/main.cc
+++ b/src/tint/cmd/tint/main.cc
@@ -775,6 +775,19 @@
     gen_options.disable_robustness = !options.enable_robustness;
     gen_options.disable_workgroup_init = options.disable_workgroup_init;
     gen_options.use_storage_input_output_16 = options.use_storage_input_output_16;
+
+    auto entry_point = inspector.GetEntryPoint(options.ep_name);
+
+    // Push constant Offset must be 4-byte aligned.
+    uint32_t offset = tint::RoundUp(4u, entry_point.push_constant_size);
+
+    if (entry_point.frag_depth_used) {
+        // Place the RangeOffset push constant member after user-defined push constants (if
+        // any).
+        gen_options.depth_range_offsets = {offset + 0, offset + 4};
+        offset += 8;
+    }
+
     gen_options.bindings = tint::spirv::writer::GenerateBindings(ir.Get());
 
     // Generate SPIR-V from Tint IR.
@@ -1159,7 +1172,9 @@
     gen_options.disable_robustness = !options.enable_robustness;
 
     auto entry_point = inspector.GetEntryPoint(options.ep_name);
-    uint32_t offset = entry_point.push_constant_size;
+
+    // Push constant Offset must be 4-byte aligned.
+    uint32_t offset = tint::RoundUp(4u, entry_point.push_constant_size);
 
     if (entry_point.instance_index_used) {
         // Place the first_instance push constant member after user-defined push constants (if
diff --git a/src/tint/lang/spirv/writer/common/options.h b/src/tint/lang/spirv/writer/common/options.h
index 1f3421b..264f2bd 100644
--- a/src/tint/lang/spirv/writer/common/options.h
+++ b/src/tint/lang/spirv/writer/common/options.h
@@ -131,6 +131,16 @@
 
 /// Configuration options used for generating SPIR-V.
 struct Options {
+    struct RangeOffsets {
+        /// The offset of the min_depth push constant
+        uint32_t min = 0;
+        /// The offset of the max_depth push constant
+        uint32_t max = 0;
+
+        /// Reflect the fields of this class so that it can be used by tint::ForeachField()
+        TINT_REFLECT(RangeOffsets, min, max);
+    };
+
     /// An optional remapped name to use when emitting the entry point.
     std::string remapped_entry_point_name = {};
 
@@ -187,6 +197,9 @@
     /// Set to `true` if the Vulkan Memory Model should be used
     bool use_vulkan_memory_model = false;
 
+    /// Offsets of the minDepth and maxDepth push constants.
+    std::optional<RangeOffsets> depth_range_offsets;
+
     /// Reflect the fields of this class so that it can be used by tint::ForeachField()
     TINT_REFLECT(Options,
                  remapped_entry_point_name,
@@ -205,7 +218,8 @@
                  pass_matrix_by_pointer,
                  polyfill_dot_4x8_packed,
                  disable_polyfill_integer_div_mod,
-                 use_vulkan_memory_model);
+                 use_vulkan_memory_model,
+                 depth_range_offsets);
 };
 
 }  // namespace tint::spirv::writer
diff --git a/src/tint/lang/spirv/writer/raise/raise.cc b/src/tint/lang/spirv/writer/raise/raise.cc
index 49519c9..4e28323 100644
--- a/src/tint/lang/spirv/writer/raise/raise.cc
+++ b/src/tint/lang/spirv/writer/raise/raise.cc
@@ -41,12 +41,14 @@
 #include "src/tint/lang/core/ir/transform/demote_to_helper.h"
 #include "src/tint/lang/core/ir/transform/direct_variable_access.h"
 #include "src/tint/lang/core/ir/transform/multiplanar_external_texture.h"
+#include "src/tint/lang/core/ir/transform/prepare_push_constants.h"
 #include "src/tint/lang/core/ir/transform/preserve_padding.h"
 #include "src/tint/lang/core/ir/transform/prevent_infinite_loops.h"
 #include "src/tint/lang/core/ir/transform/robustness.h"
 #include "src/tint/lang/core/ir/transform/std140.h"
 #include "src/tint/lang/core/ir/transform/vectorize_scalar_matrix_constructors.h"
 #include "src/tint/lang/core/ir/transform/zero_init_workgroup_memory.h"
+#include "src/tint/lang/core/type/f32.h"
 #include "src/tint/lang/spirv/writer/common/option_helpers.h"
 #include "src/tint/lang/spirv/writer/raise/builtin_polyfill.h"
 #include "src/tint/lang/spirv/writer/raise/expand_implicit_splats.h"
@@ -78,6 +80,22 @@
         RUN_TRANSFORM(core::ir::transform::PreventInfiniteLoops, module);
     }
 
+    // PreparePushConstants must come before any transform that needs internal push constants.
+    core::ir::transform::PreparePushConstantsConfig push_constant_config;
+    if (options.depth_range_offsets) {
+        push_constant_config.AddInternalConstant(options.depth_range_offsets.value().min,
+                                                 module.symbols.New("tint_frag_depth_min"),
+                                                 module.Types().f32());
+        push_constant_config.AddInternalConstant(options.depth_range_offsets.value().max,
+                                                 module.symbols.New("tint_frag_depth_max"),
+                                                 module.Types().f32());
+    }
+    auto push_constant_layout =
+        core::ir::transform::PreparePushConstants(module, push_constant_config);
+    if (push_constant_layout != Success) {
+        return push_constant_layout.Failure();
+    }
+
     core::ir::transform::BinaryPolyfillConfig binary_polyfills;
     binary_polyfills.bitshift_modulo = true;
     binary_polyfills.int_div_mod = !options.disable_polyfill_integer_div_mod;
diff --git a/test/tint/bug/tint/1666.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/1666.wgsl.expected.fxc.hlsl
index c840c35..5a211d5 100644
--- a/test/tint/bug/tint/1666.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/1666.wgsl.expected.fxc.hlsl
@@ -1,26 +1,27 @@
-SKIP: FAILED
-
 void tint_symbol() {
   int idx = 3;
-  int x = int2(1, 2)[idx];
+  int x = int2(1, 2)[min(uint(idx), 1u)];
 }
 
 void tint_symbol_1() {
   int idx = 4;
-  float2 x = float2x2(float2(1.0f, 2.0f), float2(3.0f, 4.0f))[idx];
+  float2 x = float2x2(float2(1.0f, 2.0f), float2(3.0f, 4.0f))[min(uint(idx), 1u)];
 }
 
 void fixed_size_array() {
   int arr[2] = {1, 2};
   int idx = 3;
-  int x = arr[idx];
+  int x = arr[min(uint(idx), 1u)];
 }
 
 ByteAddressBuffer rarr : register(t0);
 
 void runtime_size_array() {
+  uint tint_symbol_3 = 0u;
+  rarr.GetDimensions(tint_symbol_3);
+  uint tint_symbol_4 = (tint_symbol_3 / 4u);
   int idx = -1;
-  float x = asfloat(rarr.Load((4u * uint(idx))));
+  float x = asfloat(rarr.Load((4u * min(uint(idx), (tint_symbol_4 - 1u)))));
 }
 
 [numthreads(1, 1, 1)]
@@ -31,8 +32,3 @@
   runtime_size_array();
   return;
 }
-FXC validation failure:
-<scrubbed_path>(3,11-25): error X3504: array index out of bounds
-
-
-tint executable returned error: exit status 1
diff --git a/test/tint/types/functions/shader_io/fragment_output_builtins.wgsl.expected.spvasm b/test/tint/types/functions/shader_io/fragment_output_builtins.wgsl.expected.spvasm
index f23acbc..0ac710c 100644
--- a/test/tint/types/functions/shader_io/fragment_output_builtins.wgsl.expected.spvasm
+++ b/test/tint/types/functions/shader_io/fragment_output_builtins.wgsl.expected.spvasm
@@ -4,32 +4,42 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 13
+; Bound: 16
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %main1 "main1" %main1_frag_depth_Output
                OpExecutionMode %main1 OriginUpperLeft
                OpExecutionMode %main1 DepthReplacing
+               OpMemberName %tint_push_constant_struct 0 "tint_frag_depth_min"
+               OpMemberName %tint_push_constant_struct 1 "tint_frag_depth_max"
+               OpName %tint_push_constant_struct "tint_push_constant_struct"
+               OpName %tint_push_constants "tint_push_constants"
                OpName %main1_frag_depth_Output "main1_frag_depth_Output"
                OpName %main1_inner "main1_inner"
                OpName %main1 "main1"
+               OpMemberDecorate %tint_push_constant_struct 0 Offset 0
+               OpMemberDecorate %tint_push_constant_struct 1 Offset 4
+               OpDecorate %tint_push_constant_struct Block
                OpDecorate %main1_frag_depth_Output BuiltIn FragDepth
       %float = OpTypeFloat 32
+%tint_push_constant_struct = OpTypeStruct %float %float
+%_ptr_PushConstant_tint_push_constant_struct = OpTypePointer PushConstant %tint_push_constant_struct
+%tint_push_constants = OpVariable %_ptr_PushConstant_tint_push_constant_struct PushConstant
 %_ptr_Output_float = OpTypePointer Output %float
 %main1_frag_depth_Output = OpVariable %_ptr_Output_float Output
-          %5 = OpTypeFunction %float
+          %8 = OpTypeFunction %float
     %float_1 = OpConstant %float 1
        %void = OpTypeVoid
-         %10 = OpTypeFunction %void
-%main1_inner = OpFunction %float None %5
-          %6 = OpLabel
+         %13 = OpTypeFunction %void
+%main1_inner = OpFunction %float None %8
+          %9 = OpLabel
                OpReturnValue %float_1
                OpFunctionEnd
-      %main1 = OpFunction %void None %10
-         %11 = OpLabel
-         %12 = OpFunctionCall %float %main1_inner
-               OpStore %main1_frag_depth_Output %12 None
+      %main1 = OpFunction %void None %13
+         %14 = OpLabel
+         %15 = OpFunctionCall %float %main1_inner
+               OpStore %main1_frag_depth_Output %15 None
                OpReturn
                OpFunctionEnd
 ;
diff --git a/test/tint/types/functions/shader_io/fragment_output_builtins_struct.wgsl.expected.spvasm b/test/tint/types/functions/shader_io/fragment_output_builtins_struct.wgsl.expected.spvasm
index 7028bed..d171bcd 100644
--- a/test/tint/types/functions/shader_io/fragment_output_builtins_struct.wgsl.expected.spvasm
+++ b/test/tint/types/functions/shader_io/fragment_output_builtins_struct.wgsl.expected.spvasm
@@ -1,13 +1,17 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 25
+; Bound: 28
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %main "main" %main_frag_depth_Output %main_sample_mask_Output
                OpExecutionMode %main OriginUpperLeft
                OpExecutionMode %main DepthReplacing
+               OpMemberName %tint_push_constant_struct 0 "tint_frag_depth_min"
+               OpMemberName %tint_push_constant_struct 1 "tint_frag_depth_max"
+               OpName %tint_push_constant_struct "tint_push_constant_struct"
+               OpName %tint_push_constants "tint_push_constants"
                OpName %main_frag_depth_Output "main_frag_depth_Output"
                OpName %main_sample_mask_Output "main_sample_mask_Output"
                OpName %main_inner "main_inner"
@@ -15,12 +19,18 @@
                OpMemberName %FragmentOutputs 1 "sample_mask"
                OpName %FragmentOutputs "FragmentOutputs"
                OpName %main "main"
+               OpMemberDecorate %tint_push_constant_struct 0 Offset 0
+               OpMemberDecorate %tint_push_constant_struct 1 Offset 4
+               OpDecorate %tint_push_constant_struct Block
                OpDecorate %main_frag_depth_Output BuiltIn FragDepth
                OpDecorate %_arr_uint_uint_1 ArrayStride 4
                OpDecorate %main_sample_mask_Output BuiltIn SampleMask
                OpMemberDecorate %FragmentOutputs 0 Offset 0
                OpMemberDecorate %FragmentOutputs 1 Offset 4
       %float = OpTypeFloat 32
+%tint_push_constant_struct = OpTypeStruct %float %float
+%_ptr_PushConstant_tint_push_constant_struct = OpTypePointer PushConstant %tint_push_constant_struct
+%tint_push_constants = OpVariable %_ptr_PushConstant_tint_push_constant_struct PushConstant
 %_ptr_Output_float = OpTypePointer Output %float
 %main_frag_depth_Output = OpVariable %_ptr_Output_float Output
        %uint = OpTypeInt 32 0
@@ -29,24 +39,24 @@
 %_ptr_Output__arr_uint_uint_1 = OpTypePointer Output %_arr_uint_uint_1
 %main_sample_mask_Output = OpVariable %_ptr_Output__arr_uint_uint_1 Output
 %FragmentOutputs = OpTypeStruct %float %uint
-         %11 = OpTypeFunction %FragmentOutputs
+         %14 = OpTypeFunction %FragmentOutputs
     %float_1 = OpConstant %float 1
-         %13 = OpConstantComposite %FragmentOutputs %float_1 %uint_1
+         %16 = OpConstantComposite %FragmentOutputs %float_1 %uint_1
        %void = OpTypeVoid
-         %17 = OpTypeFunction %void
+         %20 = OpTypeFunction %void
 %_ptr_Output_uint = OpTypePointer Output %uint
      %uint_0 = OpConstant %uint 0
- %main_inner = OpFunction %FragmentOutputs None %11
-         %12 = OpLabel
-               OpReturnValue %13
+ %main_inner = OpFunction %FragmentOutputs None %14
+         %15 = OpLabel
+               OpReturnValue %16
                OpFunctionEnd
-       %main = OpFunction %void None %17
-         %18 = OpLabel
-         %19 = OpFunctionCall %FragmentOutputs %main_inner
-         %20 = OpCompositeExtract %float %19 0
-               OpStore %main_frag_depth_Output %20 None
-         %21 = OpCompositeExtract %uint %19 1
-         %22 = OpAccessChain %_ptr_Output_uint %main_sample_mask_Output %uint_0
-               OpStore %22 %21 None
+       %main = OpFunction %void None %20
+         %21 = OpLabel
+         %22 = OpFunctionCall %FragmentOutputs %main_inner
+         %23 = OpCompositeExtract %float %22 0
+               OpStore %main_frag_depth_Output %23 None
+         %24 = OpCompositeExtract %uint %22 1
+         %25 = OpAccessChain %_ptr_Output_uint %main_sample_mask_Output %uint_0
+               OpStore %25 %24 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/types/functions/shader_io/fragment_output_mixed.wgsl.expected.spvasm b/test/tint/types/functions/shader_io/fragment_output_mixed.wgsl.expected.spvasm
index 1c9b683..f6a498f 100644
--- a/test/tint/types/functions/shader_io/fragment_output_mixed.wgsl.expected.spvasm
+++ b/test/tint/types/functions/shader_io/fragment_output_mixed.wgsl.expected.spvasm
@@ -1,13 +1,17 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 46
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %main "main" %main_loc0_Output %main_frag_depth_Output %main_loc1_Output %main_loc2_Output %main_sample_mask_Output %main_loc3_Output
                OpExecutionMode %main OriginUpperLeft
                OpExecutionMode %main DepthReplacing
+               OpMemberName %tint_push_constant_struct 0 "tint_frag_depth_min"
+               OpMemberName %tint_push_constant_struct 1 "tint_frag_depth_max"
+               OpName %tint_push_constant_struct "tint_push_constant_struct"
+               OpName %tint_push_constants "tint_push_constants"
                OpName %main_loc0_Output "main_loc0_Output"
                OpName %main_frag_depth_Output "main_frag_depth_Output"
                OpName %main_loc1_Output "main_loc1_Output"
@@ -23,6 +27,9 @@
                OpMemberName %FragmentOutputs 5 "loc3"
                OpName %FragmentOutputs "FragmentOutputs"
                OpName %main "main"
+               OpMemberDecorate %tint_push_constant_struct 0 Offset 0
+               OpMemberDecorate %tint_push_constant_struct 1 Offset 4
+               OpDecorate %tint_push_constant_struct Block
                OpDecorate %main_loc0_Output Location 0
                OpDecorate %main_frag_depth_Output BuiltIn FragDepth
                OpDecorate %main_loc1_Output Location 1
@@ -36,10 +43,13 @@
                OpMemberDecorate %FragmentOutputs 3 Offset 12
                OpMemberDecorate %FragmentOutputs 4 Offset 16
                OpMemberDecorate %FragmentOutputs 5 Offset 32
+      %float = OpTypeFloat 32
+%tint_push_constant_struct = OpTypeStruct %float %float
+%_ptr_PushConstant_tint_push_constant_struct = OpTypePointer PushConstant %tint_push_constant_struct
+%tint_push_constants = OpVariable %_ptr_PushConstant_tint_push_constant_struct PushConstant
         %int = OpTypeInt 32 1
 %_ptr_Output_int = OpTypePointer Output %int
 %main_loc0_Output = OpVariable %_ptr_Output_int Output
-      %float = OpTypeFloat 32
 %_ptr_Output_float = OpTypePointer Output %float
 %main_frag_depth_Output = OpVariable %_ptr_Output_float Output
        %uint = OpTypeInt 32 0
@@ -54,37 +64,37 @@
 %_ptr_Output_v4float = OpTypePointer Output %v4float
 %main_loc3_Output = OpVariable %_ptr_Output_v4float Output
 %FragmentOutputs = OpTypeStruct %int %float %uint %float %uint %v4float
-         %20 = OpTypeFunction %FragmentOutputs
+         %23 = OpTypeFunction %FragmentOutputs
       %int_1 = OpConstant %int 1
     %float_2 = OpConstant %float 2
     %float_1 = OpConstant %float 1
      %uint_2 = OpConstant %uint 2
     %float_3 = OpConstant %float 3
     %float_4 = OpConstant %float 4
-         %27 = OpConstantComposite %v4float %float_1 %float_2 %float_3 %float_4
-         %22 = OpConstantComposite %FragmentOutputs %int_1 %float_2 %uint_1 %float_1 %uint_2 %27
+         %30 = OpConstantComposite %v4float %float_1 %float_2 %float_3 %float_4
+         %25 = OpConstantComposite %FragmentOutputs %int_1 %float_2 %uint_1 %float_1 %uint_2 %30
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
      %uint_0 = OpConstant %uint 0
- %main_inner = OpFunction %FragmentOutputs None %20
-         %21 = OpLabel
-               OpReturnValue %22
+ %main_inner = OpFunction %FragmentOutputs None %23
+         %24 = OpLabel
+               OpReturnValue %25
                OpFunctionEnd
-       %main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %FragmentOutputs %main_inner
-         %35 = OpCompositeExtract %int %34 0
-               OpStore %main_loc0_Output %35 None
-         %36 = OpCompositeExtract %float %34 1
-               OpStore %main_frag_depth_Output %36 None
-         %37 = OpCompositeExtract %uint %34 2
-               OpStore %main_loc1_Output %37 None
-         %38 = OpCompositeExtract %float %34 3
-               OpStore %main_loc2_Output %38 None
-         %39 = OpCompositeExtract %uint %34 4
-         %40 = OpAccessChain %_ptr_Output_uint %main_sample_mask_Output %uint_0
-               OpStore %40 %39 None
-         %42 = OpCompositeExtract %v4float %34 5
-               OpStore %main_loc3_Output %42 None
+       %main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %FragmentOutputs %main_inner
+         %38 = OpCompositeExtract %int %37 0
+               OpStore %main_loc0_Output %38 None
+         %39 = OpCompositeExtract %float %37 1
+               OpStore %main_frag_depth_Output %39 None
+         %40 = OpCompositeExtract %uint %37 2
+               OpStore %main_loc1_Output %40 None
+         %41 = OpCompositeExtract %float %37 3
+               OpStore %main_loc2_Output %41 None
+         %42 = OpCompositeExtract %uint %37 4
+         %43 = OpAccessChain %_ptr_Output_uint %main_sample_mask_Output %uint_0
+               OpStore %43 %42 None
+         %45 = OpCompositeExtract %v4float %37 5
+               OpStore %main_loc3_Output %45 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/types/functions/shader_io/fragment_output_mixed_f16.wgsl.expected.spvasm b/test/tint/types/functions/shader_io/fragment_output_mixed_f16.wgsl.expected.spvasm
index 5c7a3b1..aa28337 100644
--- a/test/tint/types/functions/shader_io/fragment_output_mixed_f16.wgsl.expected.spvasm
+++ b/test/tint/types/functions/shader_io/fragment_output_mixed_f16.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 59
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -12,6 +12,10 @@
                OpEntryPoint Fragment %main "main" %main_loc0_Output %main_frag_depth_Output %main_loc1_Output %main_loc2_Output %main_sample_mask_Output %main_loc3_Output %main_loc4_Output %main_loc5_Output
                OpExecutionMode %main OriginUpperLeft
                OpExecutionMode %main DepthReplacing
+               OpMemberName %tint_push_constant_struct 0 "tint_frag_depth_min"
+               OpMemberName %tint_push_constant_struct 1 "tint_frag_depth_max"
+               OpName %tint_push_constant_struct "tint_push_constant_struct"
+               OpName %tint_push_constants "tint_push_constants"
                OpName %main_loc0_Output "main_loc0_Output"
                OpName %main_frag_depth_Output "main_frag_depth_Output"
                OpName %main_loc1_Output "main_loc1_Output"
@@ -31,6 +35,9 @@
                OpMemberName %FragmentOutputs 7 "loc5"
                OpName %FragmentOutputs "FragmentOutputs"
                OpName %main "main"
+               OpMemberDecorate %tint_push_constant_struct 0 Offset 0
+               OpMemberDecorate %tint_push_constant_struct 1 Offset 4
+               OpDecorate %tint_push_constant_struct Block
                OpDecorate %main_loc0_Output Location 0
                OpDecorate %main_frag_depth_Output BuiltIn FragDepth
                OpDecorate %main_loc1_Output Location 1
@@ -48,10 +55,13 @@
                OpMemberDecorate %FragmentOutputs 5 Offset 32
                OpMemberDecorate %FragmentOutputs 6 Offset 48
                OpMemberDecorate %FragmentOutputs 7 Offset 56
+      %float = OpTypeFloat 32
+%tint_push_constant_struct = OpTypeStruct %float %float
+%_ptr_PushConstant_tint_push_constant_struct = OpTypePointer PushConstant %tint_push_constant_struct
+%tint_push_constants = OpVariable %_ptr_PushConstant_tint_push_constant_struct PushConstant
         %int = OpTypeInt 32 1
 %_ptr_Output_int = OpTypePointer Output %int
 %main_loc0_Output = OpVariable %_ptr_Output_int Output
-      %float = OpTypeFloat 32
 %_ptr_Output_float = OpTypePointer Output %float
 %main_frag_depth_Output = OpVariable %_ptr_Output_float Output
        %uint = OpTypeInt 32 0
@@ -72,46 +82,46 @@
 %_ptr_Output_v3half = OpTypePointer Output %v3half
 %main_loc5_Output = OpVariable %_ptr_Output_v3half Output
 %FragmentOutputs = OpTypeStruct %int %float %uint %float %uint %v4float %half %v3half
-         %26 = OpTypeFunction %FragmentOutputs
+         %29 = OpTypeFunction %FragmentOutputs
       %int_1 = OpConstant %int 1
     %float_2 = OpConstant %float 2
     %float_1 = OpConstant %float 1
      %uint_2 = OpConstant %uint 2
     %float_3 = OpConstant %float 3
     %float_4 = OpConstant %float 4
-         %33 = OpConstantComposite %v4float %float_1 %float_2 %float_3 %float_4
+         %36 = OpConstantComposite %v4float %float_1 %float_2 %float_3 %float_4
 %half_0x1_2p_1 = OpConstant %half 0x1.2p+1
 %half_0x1_8p_1 = OpConstant %half 0x1.8p+1
 %half_0x1_4p_2 = OpConstant %half 0x1.4p+2
 %half_0x1p_3 = OpConstant %half 0x1p+3
-         %37 = OpConstantComposite %v3half %half_0x1_8p_1 %half_0x1_4p_2 %half_0x1p_3
-         %28 = OpConstantComposite %FragmentOutputs %int_1 %float_2 %uint_1 %float_1 %uint_2 %33 %half_0x1_2p_1 %37
+         %40 = OpConstantComposite %v3half %half_0x1_8p_1 %half_0x1_4p_2 %half_0x1p_3
+         %31 = OpConstantComposite %FragmentOutputs %int_1 %float_2 %uint_1 %float_1 %uint_2 %36 %half_0x1_2p_1 %40
        %void = OpTypeVoid
-         %43 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
      %uint_0 = OpConstant %uint 0
- %main_inner = OpFunction %FragmentOutputs None %26
-         %27 = OpLabel
-               OpReturnValue %28
+ %main_inner = OpFunction %FragmentOutputs None %29
+         %30 = OpLabel
+               OpReturnValue %31
                OpFunctionEnd
-       %main = OpFunction %void None %43
-         %44 = OpLabel
-         %45 = OpFunctionCall %FragmentOutputs %main_inner
-         %46 = OpCompositeExtract %int %45 0
-               OpStore %main_loc0_Output %46 None
-         %47 = OpCompositeExtract %float %45 1
-               OpStore %main_frag_depth_Output %47 None
-         %48 = OpCompositeExtract %uint %45 2
-               OpStore %main_loc1_Output %48 None
-         %49 = OpCompositeExtract %float %45 3
-               OpStore %main_loc2_Output %49 None
-         %50 = OpCompositeExtract %uint %45 4
-         %51 = OpAccessChain %_ptr_Output_uint %main_sample_mask_Output %uint_0
-               OpStore %51 %50 None
-         %53 = OpCompositeExtract %v4float %45 5
-               OpStore %main_loc3_Output %53 None
-         %54 = OpCompositeExtract %half %45 6
-               OpStore %main_loc4_Output %54 None
-         %55 = OpCompositeExtract %v3half %45 7
-               OpStore %main_loc5_Output %55 None
+       %main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %FragmentOutputs %main_inner
+         %49 = OpCompositeExtract %int %48 0
+               OpStore %main_loc0_Output %49 None
+         %50 = OpCompositeExtract %float %48 1
+               OpStore %main_frag_depth_Output %50 None
+         %51 = OpCompositeExtract %uint %48 2
+               OpStore %main_loc1_Output %51 None
+         %52 = OpCompositeExtract %float %48 3
+               OpStore %main_loc2_Output %52 None
+         %53 = OpCompositeExtract %uint %48 4
+         %54 = OpAccessChain %_ptr_Output_uint %main_sample_mask_Output %uint_0
+               OpStore %54 %53 None
+         %56 = OpCompositeExtract %v4float %48 5
+               OpStore %main_loc3_Output %56 None
+         %57 = OpCompositeExtract %half %48 6
+               OpStore %main_loc4_Output %57 None
+         %58 = OpCompositeExtract %v3half %48 7
+               OpStore %main_loc5_Output %58 None
                OpReturn
                OpFunctionEnd