tint: Preserve padding in matrices with three rows

The PreservePadding transform now decomposes writes to matrices with
three rows into separate column vector writes, to avoid modifying
padding between columns.

Bug: tint:1571
Change-Id: If575f79bb87f52810783fd3338e2f3ce3228ab2e
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/121600
Auto-Submit: James Price <jrprice@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: James Price <jrprice@google.com>
diff --git a/src/tint/transform/preserve_padding.cc b/src/tint/transform/preserve_padding.cc
index cb5a8ee..fbe785c 100644
--- a/src/tint/transform/preserve_padding.cc
+++ b/src/tint/transform/preserve_padding.cc
@@ -147,6 +147,18 @@
                     return body;
                 });
             },
+            [&](const type::Matrix* mat) {
+                // Call a helper function that assigns each column separately.
+                return call_helper([&]() {
+                    utils::Vector<const ast::Statement*, 4> body;
+                    for (uint32_t i = 0; i < mat->columns(); i++) {
+                        body.Push(MakeAssignment(mat->ColumnType(),
+                                                 b.IndexAccessor(b.Deref(kDestParamName), u32(i)),
+                                                 b.IndexAccessor(kValueParamName, u32(i))));
+                    }
+                    return body;
+                });
+            },
             [&](const sem::Struct* str) {
                 // Call a helper function that assigns each member separately.
                 return call_helper([&]() {
@@ -179,6 +191,13 @@
                 }
                 return HasPadding(elem_ty);
             },
+            [&](const type::Matrix* mat) {
+                auto* col_ty = mat->ColumnType();
+                if (mat->ColumnStride() > col_ty->Size()) {
+                    return true;
+                }
+                return HasPadding(col_ty);
+            },
             [&](const sem::Struct* str) {
                 uint32_t current_offset = 0;
                 for (auto* member : str->Members()) {
diff --git a/src/tint/transform/preserve_padding_test.cc b/src/tint/transform/preserve_padding_test.cc
index 9405210..2b4869a 100644
--- a/src/tint/transform/preserve_padding_test.cc
+++ b/src/tint/transform/preserve_padding_test.cc
@@ -466,6 +466,125 @@
     EXPECT_EQ(expect, str(got));
 }
 
+TEST_F(PreservePaddingTest, Mat3x3) {
+    auto* src = R"(
+@group(0) @binding(0) var<storage, read_write> m : mat3x3<f32>;
+
+@compute @workgroup_size(1)
+fn foo() {
+  m = mat3x3<f32>();
+}
+)";
+
+    auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+@group(0) @binding(0) var<storage, read_write> m : mat3x3<f32>;
+
+fn assign_and_preserve_padding(dest : ptr<storage, mat3x3<f32>, read_write>, value : mat3x3<f32>) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+}
+
+@compute @workgroup_size(1)
+fn foo() {
+  assign_and_preserve_padding(&(m), mat3x3<f32>());
+}
+)";
+
+    auto got = Run<PreservePadding>(src);
+
+    EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PreservePaddingTest, Mat3x3_InStruct) {
+    auto* src = R"(
+struct S {
+  a : u32,
+  m : mat3x3<f32>,
+}
+
+@group(0) @binding(0) var<storage, read_write> buffer : S;
+
+@compute @workgroup_size(1)
+fn foo() {
+  buffer = S();
+}
+)";
+
+    auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct S {
+  a : u32,
+  m : mat3x3<f32>,
+}
+
+@group(0) @binding(0) var<storage, read_write> buffer : S;
+
+fn assign_and_preserve_padding_1(dest : ptr<storage, mat3x3<f32>, read_write>, value : mat3x3<f32>) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+}
+
+fn assign_and_preserve_padding(dest : ptr<storage, S, read_write>, value : S) {
+  (*(dest)).a = value.a;
+  assign_and_preserve_padding_1(&((*(dest)).m), value.m);
+}
+
+@compute @workgroup_size(1)
+fn foo() {
+  assign_and_preserve_padding(&(buffer), S());
+}
+)";
+
+    auto got = Run<PreservePadding>(src);
+
+    EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PreservePaddingTest, ArrayOfMat3x3) {
+    auto* src = R"(
+@group(0) @binding(0) var<storage, read_write> arr_m : array<mat3x3<f32>, 4>;
+
+@compute @workgroup_size(1)
+fn foo() {
+  arr_m = array<mat3x3<f32>, 4>();
+  arr_m[0] = mat3x3<f32>();
+}
+)";
+
+    auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+@group(0) @binding(0) var<storage, read_write> arr_m : array<mat3x3<f32>, 4>;
+
+fn assign_and_preserve_padding_1(dest : ptr<storage, mat3x3<f32>, read_write>, value : mat3x3<f32>) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+}
+
+fn assign_and_preserve_padding(dest : ptr<storage, array<mat3x3<f32>, 4u>, read_write>, value : array<mat3x3<f32>, 4u>) {
+  for(var i = 0u; (i < 4u); i = (i + 1u)) {
+    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+  }
+}
+
+@compute @workgroup_size(1)
+fn foo() {
+  assign_and_preserve_padding(&(arr_m), array<mat3x3<f32>, 4>());
+  assign_and_preserve_padding_1(&(arr_m[0]), mat3x3<f32>());
+}
+)";
+
+    auto got = Run<PreservePadding>(src);
+
+    EXPECT_EQ(expect, str(got));
+}
+
 TEST_F(PreservePaddingTest, NoModify_Vec3) {
     auto* src = R"(
 @group(0) @binding(0) var<storage, read_write> v : vec3<u32>;
@@ -524,23 +643,6 @@
     EXPECT_EQ(expect, str(got));
 }
 
-TEST_F(PreservePaddingTest, NoModify_Mat3x3) {
-    auto* src = R"(
-@group(0) @binding(0) var<storage, read_write> v : mat3x3<f32>;
-
-@compute @workgroup_size(1)
-fn foo() {
-  v = mat3x3<f32>();
-}
-)";
-
-    auto* expect = src;
-
-    auto got = Run<PreservePadding>(src);
-
-    EXPECT_EQ(expect, str(got));
-}
-
 TEST_F(PreservePaddingTest, NoModify_StructNoPadding) {
     auto* src = R"(
 struct S {
diff --git a/src/tint/writer/glsl/generator_impl_member_accessor_test.cc b/src/tint/writer/glsl/generator_impl_member_accessor_test.cc
index e551c75..2eb1b8e 100644
--- a/src/tint/writer/glsl/generator_impl_member_accessor_test.cc
+++ b/src/tint/writer/glsl/generator_impl_member_accessor_test.cc
@@ -241,13 +241,22 @@
                                          TypeCase{ty_vec4<f32>, "data.inner.b = value"},
                                          TypeCase{ty_vec4<i32>, "data.inner.b = value"},
                                          TypeCase{ty_mat2x2<f32>, "data.inner.b = value"},
-                                         TypeCase{ty_mat2x3<f32>, "data.inner.b = value"},
+                                         TypeCase{ty_mat2x3<f32>, R"(
+  data.inner.b[0] = value[0u];
+  data.inner.b[1] = value[1u];)"},
                                          TypeCase{ty_mat2x4<f32>, "data.inner.b = value"},
                                          TypeCase{ty_mat3x2<f32>, "data.inner.b = value"},
-                                         TypeCase{ty_mat3x3<f32>, "data.inner.b = value"},
+                                         TypeCase{ty_mat3x3<f32>, R"(
+  data.inner.b[0] = value[0u];
+  data.inner.b[1] = value[1u];
+  data.inner.b[2] = value[2u];)"},
                                          TypeCase{ty_mat3x4<f32>, "data.inner.b = value"},
                                          TypeCase{ty_mat4x2<f32>, "data.inner.b = value"},
-                                         TypeCase{ty_mat4x3<f32>, "data.inner.b = value"},
+                                         TypeCase{ty_mat4x3<f32>, R"(
+  data.inner.b[0] = value[0u];
+  data.inner.b[1] = value[1u];
+  data.inner.b[2] = value[2u];
+  data.inner.b[3] = value[3u];)"},
                                          TypeCase{ty_mat4x4<f32>, "data.inner.b = value"}));
 
 TEST_F(GlslGeneratorImplTest_MemberAccessor, StorageBuffer_Store_Matrix_Empty) {
@@ -286,8 +295,13 @@
   Data inner;
 } data;
 
+void assign_and_preserve_padding_data_b(mat2x3 value) {
+  data.inner.b[0] = value[0u];
+  data.inner.b[1] = value[1u];
+}
+
 void tint_symbol() {
-  data.inner.b = mat2x3(vec3(0.0f), vec3(0.0f));
+  assign_and_preserve_padding_data_b(mat2x3(vec3(0.0f), vec3(0.0f)));
 }
 
 void main() {
diff --git a/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.glsl b/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.glsl
index 5b93fa5..f353143 100644
--- a/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.glsl
+++ b/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.glsl
@@ -37,7 +37,25 @@
   Inner arr[];
 } sb;
 
-void assign_and_preserve_padding_sb_arr_X_arr2_vec3_f32(uint dest[1], vec3 value[2]) {
+void assign_and_preserve_padding_sb_arr_X_mat2x3_f32(uint dest[1], mat2x3 value) {
+  sb.arr[dest[0]].mat2x3_f32[0] = value[0u];
+  sb.arr[dest[0]].mat2x3_f32[1] = value[1u];
+}
+
+void assign_and_preserve_padding_1_sb_arr_X_mat3x3_f32(uint dest[1], mat3 value) {
+  sb.arr[dest[0]].mat3x3_f32[0] = value[0u];
+  sb.arr[dest[0]].mat3x3_f32[1] = value[1u];
+  sb.arr[dest[0]].mat3x3_f32[2] = value[2u];
+}
+
+void assign_and_preserve_padding_2_sb_arr_X_mat4x3_f32(uint dest[1], mat4x3 value) {
+  sb.arr[dest[0]].mat4x3_f32[0] = value[0u];
+  sb.arr[dest[0]].mat4x3_f32[1] = value[1u];
+  sb.arr[dest[0]].mat4x3_f32[2] = value[2u];
+  sb.arr[dest[0]].mat4x3_f32[3] = value[3u];
+}
+
+void assign_and_preserve_padding_3_sb_arr_X_arr2_vec3_f32(uint dest[1], vec3 value[2]) {
   {
     for(uint i = 0u; (i < 2u); i = (i + 1u)) {
       sb.arr[dest[0]].arr2_vec3_f32[i] = value[i];
@@ -59,17 +77,20 @@
   sb.arr[idx].vec4_i32 = ivec4(0);
   sb.arr[idx].vec4_u32 = uvec4(0u);
   sb.arr[idx].mat2x2_f32 = mat2(vec2(0.0f), vec2(0.0f));
-  sb.arr[idx].mat2x3_f32 = mat2x3(vec3(0.0f), vec3(0.0f));
+  uint tint_symbol_1[1] = uint[1](idx);
+  assign_and_preserve_padding_sb_arr_X_mat2x3_f32(tint_symbol_1, mat2x3(vec3(0.0f), vec3(0.0f)));
   sb.arr[idx].mat2x4_f32 = mat2x4(vec4(0.0f), vec4(0.0f));
   sb.arr[idx].mat3x2_f32 = mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f));
-  sb.arr[idx].mat3x3_f32 = mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f));
+  uint tint_symbol_2[1] = uint[1](idx);
+  assign_and_preserve_padding_1_sb_arr_X_mat3x3_f32(tint_symbol_2, mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f)));
   sb.arr[idx].mat3x4_f32 = mat3x4(vec4(0.0f), vec4(0.0f), vec4(0.0f));
   sb.arr[idx].mat4x2_f32 = mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f));
-  sb.arr[idx].mat4x3_f32 = mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f));
+  uint tint_symbol_3[1] = uint[1](idx);
+  assign_and_preserve_padding_2_sb_arr_X_mat4x3_f32(tint_symbol_3, mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f)));
   sb.arr[idx].mat4x4_f32 = mat4(vec4(0.0f), vec4(0.0f), vec4(0.0f), vec4(0.0f));
-  uint tint_symbol_1[1] = uint[1](idx);
-  vec3 tint_symbol_2[2] = vec3[2](vec3(0.0f), vec3(0.0f));
-  assign_and_preserve_padding_sb_arr_X_arr2_vec3_f32(tint_symbol_1, tint_symbol_2);
+  uint tint_symbol_4[1] = uint[1](idx);
+  vec3 tint_symbol_5[2] = vec3[2](vec3(0.0f), vec3(0.0f));
+  assign_and_preserve_padding_3_sb_arr_X_arr2_vec3_f32(tint_symbol_4, tint_symbol_5);
 }
 
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.msl b/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.msl
index fd9e55a..efb7ae4 100644
--- a/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.msl
+++ b/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.msl
@@ -49,7 +49,25 @@
   /* 0x0000 */ tint_array<Inner, 1> arr;
 };
 
-void assign_and_preserve_padding(device tint_array<float3, 2>* const dest, tint_array<float3, 2> value) {
+void assign_and_preserve_padding(device float2x3* const dest, float2x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+}
+
+void assign_and_preserve_padding_1(device float3x3* const dest, float3x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+}
+
+void assign_and_preserve_padding_2(device float4x3* const dest, float4x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+  (*(dest))[3u] = value[3u];
+}
+
+void assign_and_preserve_padding_3(device tint_array<float3, 2>* const dest, tint_array<float3, 2> value) {
   for(uint i = 0u; (i < 2u); i = (i + 1u)) {
     (*(dest))[i] = value[i];
   }
@@ -69,16 +87,16 @@
   (*(tint_symbol_2)).arr[idx].vec4_i32 = int4(0);
   (*(tint_symbol_2)).arr[idx].vec4_u32 = uint4(0u);
   (*(tint_symbol_2)).arr[idx].mat2x2_f32 = float2x2(float2(0.0f), float2(0.0f));
-  (*(tint_symbol_2)).arr[idx].mat2x3_f32 = float2x3(float3(0.0f), float3(0.0f));
+  assign_and_preserve_padding(&((*(tint_symbol_2)).arr[idx].mat2x3_f32), float2x3(float3(0.0f), float3(0.0f)));
   (*(tint_symbol_2)).arr[idx].mat2x4_f32 = float2x4(float4(0.0f), float4(0.0f));
   (*(tint_symbol_2)).arr[idx].mat3x2_f32 = float3x2(float2(0.0f), float2(0.0f), float2(0.0f));
-  (*(tint_symbol_2)).arr[idx].mat3x3_f32 = float3x3(float3(0.0f), float3(0.0f), float3(0.0f));
+  assign_and_preserve_padding_1(&((*(tint_symbol_2)).arr[idx].mat3x3_f32), float3x3(float3(0.0f), float3(0.0f), float3(0.0f)));
   (*(tint_symbol_2)).arr[idx].mat3x4_f32 = float3x4(float4(0.0f), float4(0.0f), float4(0.0f));
   (*(tint_symbol_2)).arr[idx].mat4x2_f32 = float4x2(float2(0.0f), float2(0.0f), float2(0.0f), float2(0.0f));
-  (*(tint_symbol_2)).arr[idx].mat4x3_f32 = float4x3(float3(0.0f), float3(0.0f), float3(0.0f), float3(0.0f));
+  assign_and_preserve_padding_2(&((*(tint_symbol_2)).arr[idx].mat4x3_f32), float4x3(float3(0.0f), float3(0.0f), float3(0.0f), float3(0.0f)));
   (*(tint_symbol_2)).arr[idx].mat4x4_f32 = float4x4(float4(0.0f), float4(0.0f), float4(0.0f), float4(0.0f));
   tint_array<float3, 2> const tint_symbol_1 = tint_array<float3, 2>{};
-  assign_and_preserve_padding(&((*(tint_symbol_2)).arr[idx].arr2_vec3_f32), tint_symbol_1);
+  assign_and_preserve_padding_3(&((*(tint_symbol_2)).arr[idx].arr2_vec3_f32), tint_symbol_1);
 }
 
 kernel void tint_symbol(device S* tint_symbol_3 [[buffer(0)]], uint idx [[thread_index_in_threadgroup]]) {
diff --git a/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.spvasm b/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.spvasm
index ace1368..e4cbd7e 100644
--- a/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.spvasm
+++ b/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 157
+; Bound: 199
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -34,9 +34,18 @@
                OpMemberName %Inner 20 "mat4x4_f32"
                OpMemberName %Inner 21 "arr2_vec3_f32"
                OpName %sb "sb"
-               OpName %assign_and_preserve_padding_sb_arr_X_arr2_vec3_f32 "assign_and_preserve_padding_sb_arr_X_arr2_vec3_f32"
+               OpName %assign_and_preserve_padding_sb_arr_X_mat2x3_f32 "assign_and_preserve_padding_sb_arr_X_mat2x3_f32"
                OpName %dest "dest"
                OpName %value "value"
+               OpName %assign_and_preserve_padding_1_sb_arr_X_mat3x3_f32 "assign_and_preserve_padding_1_sb_arr_X_mat3x3_f32"
+               OpName %dest_0 "dest"
+               OpName %value_0 "value"
+               OpName %assign_and_preserve_padding_2_sb_arr_X_mat4x3_f32 "assign_and_preserve_padding_2_sb_arr_X_mat4x3_f32"
+               OpName %dest_1 "dest"
+               OpName %value_1 "value"
+               OpName %assign_and_preserve_padding_3_sb_arr_X_arr2_vec3_f32 "assign_and_preserve_padding_3_sb_arr_X_arr2_vec3_f32"
+               OpName %dest_2 "dest"
+               OpName %value_2 "value"
                OpName %i "i"
                OpName %var_for_index "var_for_index"
                OpName %main_inner "main_inner"
@@ -123,165 +132,219 @@
        %void = OpTypeVoid
      %uint_1 = OpConstant %uint 1
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
-         %31 = OpTypeFunction %void %_arr_uint_uint_1 %_arr_v3float_uint_2
-         %39 = OpConstantNull %uint
+         %31 = OpTypeFunction %void %_arr_uint_uint_1 %mat2v3float
+     %uint_0 = OpConstant %uint 0
+         %40 = OpConstantNull %int
+    %uint_13 = OpConstant %uint 13
+%_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
+         %45 = OpConstantNull %uint
+      %int_1 = OpConstant %int 1
+         %51 = OpTypeFunction %void %_arr_uint_uint_1 %mat3v3float
+    %uint_16 = OpConstant %uint 16
+      %int_2 = OpConstant %int 2
+         %67 = OpTypeFunction %void %_arr_uint_uint_1 %mat4v3float
+    %uint_19 = OpConstant %uint 19
+      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
+         %87 = OpTypeFunction %void %_arr_uint_uint_1 %_arr_v3float_uint_2
 %_ptr_Function_uint = OpTypePointer Function %uint
        %bool = OpTypeBool
 %_ptr_Function__arr_v3float_uint_2 = OpTypePointer Function %_arr_v3float_uint_2
-         %54 = OpConstantNull %_arr_v3float_uint_2
-     %uint_0 = OpConstant %uint 0
-         %56 = OpConstantNull %int
+        %106 = OpConstantNull %_arr_v3float_uint_2
     %uint_21 = OpConstant %uint 21
-%_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
 %_ptr_Function_v3float = OpTypePointer Function %v3float
-         %68 = OpTypeFunction %void %uint
+        %117 = OpTypeFunction %void %uint
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-         %74 = OpConstantNull %float
+        %123 = OpConstantNull %float
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-     %uint_3 = OpConstant %uint 3
 %_ptr_StorageBuffer_v2float = OpTypePointer StorageBuffer %v2float
-         %82 = OpConstantNull %v2float
+        %130 = OpConstantNull %v2float
      %uint_4 = OpConstant %uint 4
 %_ptr_StorageBuffer_v2int = OpTypePointer StorageBuffer %v2int
-         %86 = OpConstantNull %v2int
+        %134 = OpConstantNull %v2int
      %uint_5 = OpConstant %uint 5
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
-         %90 = OpConstantNull %v2uint
+        %138 = OpConstantNull %v2uint
      %uint_6 = OpConstant %uint 6
-         %93 = OpConstantNull %v3float
+        %141 = OpConstantNull %v3float
      %uint_7 = OpConstant %uint 7
 %_ptr_StorageBuffer_v3int = OpTypePointer StorageBuffer %v3int
-         %97 = OpConstantNull %v3int
+        %145 = OpConstantNull %v3int
      %uint_8 = OpConstant %uint 8
 %_ptr_StorageBuffer_v3uint = OpTypePointer StorageBuffer %v3uint
-        %101 = OpConstantNull %v3uint
+        %149 = OpConstantNull %v3uint
      %uint_9 = OpConstant %uint 9
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-        %105 = OpConstantNull %v4float
+        %153 = OpConstantNull %v4float
     %uint_10 = OpConstant %uint 10
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-        %109 = OpConstantNull %v4int
+        %157 = OpConstantNull %v4int
     %uint_11 = OpConstant %uint 11
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
-        %113 = OpConstantNull %v4uint
+        %161 = OpConstantNull %v4uint
     %uint_12 = OpConstant %uint 12
 %_ptr_StorageBuffer_mat2v2float = OpTypePointer StorageBuffer %mat2v2float
-        %117 = OpConstantNull %mat2v2float
-    %uint_13 = OpConstant %uint 13
-%_ptr_StorageBuffer_mat2v3float = OpTypePointer StorageBuffer %mat2v3float
-        %121 = OpConstantNull %mat2v3float
+        %165 = OpConstantNull %mat2v2float
+        %168 = OpConstantNull %mat2v3float
     %uint_14 = OpConstant %uint 14
 %_ptr_StorageBuffer_mat2v4float = OpTypePointer StorageBuffer %mat2v4float
-        %125 = OpConstantNull %mat2v4float
+        %172 = OpConstantNull %mat2v4float
     %uint_15 = OpConstant %uint 15
 %_ptr_StorageBuffer_mat3v2float = OpTypePointer StorageBuffer %mat3v2float
-        %129 = OpConstantNull %mat3v2float
-    %uint_16 = OpConstant %uint 16
-%_ptr_StorageBuffer_mat3v3float = OpTypePointer StorageBuffer %mat3v3float
-        %133 = OpConstantNull %mat3v3float
+        %176 = OpConstantNull %mat3v2float
+        %178 = OpConstantNull %mat3v3float
     %uint_17 = OpConstant %uint 17
 %_ptr_StorageBuffer_mat3v4float = OpTypePointer StorageBuffer %mat3v4float
-        %137 = OpConstantNull %mat3v4float
+        %182 = OpConstantNull %mat3v4float
     %uint_18 = OpConstant %uint 18
 %_ptr_StorageBuffer_mat4v2float = OpTypePointer StorageBuffer %mat4v2float
-        %141 = OpConstantNull %mat4v2float
-    %uint_19 = OpConstant %uint 19
-%_ptr_StorageBuffer_mat4v3float = OpTypePointer StorageBuffer %mat4v3float
-        %145 = OpConstantNull %mat4v3float
+        %186 = OpConstantNull %mat4v2float
+        %188 = OpConstantNull %mat4v3float
     %uint_20 = OpConstant %uint 20
 %_ptr_StorageBuffer_mat4v4float = OpTypePointer StorageBuffer %mat4v4float
-        %149 = OpConstantNull %mat4v4float
-        %152 = OpTypeFunction %void
-%assign_and_preserve_padding_sb_arr_X_arr2_vec3_f32 = OpFunction %void None %31
+        %192 = OpConstantNull %mat4v4float
+        %194 = OpTypeFunction %void
+%assign_and_preserve_padding_sb_arr_X_mat2x3_f32 = OpFunction %void None %31
        %dest = OpFunctionParameter %_arr_uint_uint_1
-      %value = OpFunctionParameter %_arr_v3float_uint_2
+      %value = OpFunctionParameter %mat2v3float
          %38 = OpLabel
-          %i = OpVariable %_ptr_Function_uint Function %39
-%var_for_index = OpVariable %_ptr_Function__arr_v3float_uint_2 Function %54
-               OpStore %i %39
-               OpBranch %42
-         %42 = OpLabel
-               OpLoopMerge %43 %44 None
-               OpBranch %45
-         %45 = OpLabel
-         %47 = OpLoad %uint %i
-         %48 = OpULessThan %bool %47 %uint_2
-         %46 = OpLogicalNot %bool %48
-               OpSelectionMerge %50 None
-               OpBranchConditional %46 %51 %50
-         %51 = OpLabel
-               OpBranch %43
-         %50 = OpLabel
-               OpStore %var_for_index %value
-         %57 = OpCompositeExtract %uint %dest 0
-         %59 = OpLoad %uint %i
-         %61 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %57 %uint_21 %59
-         %62 = OpLoad %uint %i
-         %64 = OpAccessChain %_ptr_Function_v3float %var_for_index %62
-         %65 = OpLoad %v3float %64
-               OpStore %61 %65
-               OpBranch %44
-         %44 = OpLabel
-         %66 = OpLoad %uint %i
-         %67 = OpIAdd %uint %66 %uint_1
-               OpStore %i %67
-               OpBranch %42
-         %43 = OpLabel
+         %41 = OpCompositeExtract %uint %dest 0
+         %44 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %41 %uint_13 %40
+         %46 = OpCompositeExtract %v3float %value 0
+               OpStore %44 %46
+         %47 = OpCompositeExtract %uint %dest 0
+         %49 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %47 %uint_13 %int_1
+         %50 = OpCompositeExtract %v3float %value 1
+               OpStore %49 %50
                OpReturn
                OpFunctionEnd
- %main_inner = OpFunction %void None %68
-        %idx = OpFunctionParameter %uint
+%assign_and_preserve_padding_1_sb_arr_X_mat3x3_f32 = OpFunction %void None %51
+     %dest_0 = OpFunctionParameter %_arr_uint_uint_1
+    %value_0 = OpFunctionParameter %mat3v3float
+         %55 = OpLabel
+         %56 = OpCompositeExtract %uint %dest_0 0
+         %58 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %56 %uint_16 %40
+         %59 = OpCompositeExtract %v3float %value_0 0
+               OpStore %58 %59
+         %60 = OpCompositeExtract %uint %dest_0 0
+         %61 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %60 %uint_16 %int_1
+         %62 = OpCompositeExtract %v3float %value_0 1
+               OpStore %61 %62
+         %63 = OpCompositeExtract %uint %dest_0 0
+         %65 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %63 %uint_16 %int_2
+         %66 = OpCompositeExtract %v3float %value_0 2
+               OpStore %65 %66
+               OpReturn
+               OpFunctionEnd
+%assign_and_preserve_padding_2_sb_arr_X_mat4x3_f32 = OpFunction %void None %67
+     %dest_1 = OpFunctionParameter %_arr_uint_uint_1
+    %value_1 = OpFunctionParameter %mat4v3float
          %71 = OpLabel
-         %73 = OpAccessChain %_ptr_StorageBuffer_float %sb %uint_0 %idx %uint_0
-               OpStore %73 %74
-         %76 = OpAccessChain %_ptr_StorageBuffer_int %sb %uint_0 %idx %uint_1
-               OpStore %76 %56
-         %78 = OpAccessChain %_ptr_StorageBuffer_uint %sb %uint_0 %idx %uint_2
-               OpStore %78 %39
-         %81 = OpAccessChain %_ptr_StorageBuffer_v2float %sb %uint_0 %idx %uint_3
-               OpStore %81 %82
-         %85 = OpAccessChain %_ptr_StorageBuffer_v2int %sb %uint_0 %idx %uint_4
-               OpStore %85 %86
-         %89 = OpAccessChain %_ptr_StorageBuffer_v2uint %sb %uint_0 %idx %uint_5
-               OpStore %89 %90
-         %92 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %idx %uint_6
-               OpStore %92 %93
-         %96 = OpAccessChain %_ptr_StorageBuffer_v3int %sb %uint_0 %idx %uint_7
-               OpStore %96 %97
-        %100 = OpAccessChain %_ptr_StorageBuffer_v3uint %sb %uint_0 %idx %uint_8
-               OpStore %100 %101
-        %104 = OpAccessChain %_ptr_StorageBuffer_v4float %sb %uint_0 %idx %uint_9
-               OpStore %104 %105
-        %108 = OpAccessChain %_ptr_StorageBuffer_v4int %sb %uint_0 %idx %uint_10
-               OpStore %108 %109
-        %112 = OpAccessChain %_ptr_StorageBuffer_v4uint %sb %uint_0 %idx %uint_11
-               OpStore %112 %113
-        %116 = OpAccessChain %_ptr_StorageBuffer_mat2v2float %sb %uint_0 %idx %uint_12
-               OpStore %116 %117
-        %120 = OpAccessChain %_ptr_StorageBuffer_mat2v3float %sb %uint_0 %idx %uint_13
-               OpStore %120 %121
-        %124 = OpAccessChain %_ptr_StorageBuffer_mat2v4float %sb %uint_0 %idx %uint_14
-               OpStore %124 %125
-        %128 = OpAccessChain %_ptr_StorageBuffer_mat3v2float %sb %uint_0 %idx %uint_15
-               OpStore %128 %129
-        %132 = OpAccessChain %_ptr_StorageBuffer_mat3v3float %sb %uint_0 %idx %uint_16
-               OpStore %132 %133
-        %136 = OpAccessChain %_ptr_StorageBuffer_mat3v4float %sb %uint_0 %idx %uint_17
-               OpStore %136 %137
-        %140 = OpAccessChain %_ptr_StorageBuffer_mat4v2float %sb %uint_0 %idx %uint_18
-               OpStore %140 %141
-        %144 = OpAccessChain %_ptr_StorageBuffer_mat4v3float %sb %uint_0 %idx %uint_19
-               OpStore %144 %145
-        %148 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %sb %uint_0 %idx %uint_20
-               OpStore %148 %149
-        %151 = OpCompositeConstruct %_arr_uint_uint_1 %idx
-        %150 = OpFunctionCall %void %assign_and_preserve_padding_sb_arr_X_arr2_vec3_f32 %151 %54
+         %72 = OpCompositeExtract %uint %dest_1 0
+         %74 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %72 %uint_19 %40
+         %75 = OpCompositeExtract %v3float %value_1 0
+               OpStore %74 %75
+         %76 = OpCompositeExtract %uint %dest_1 0
+         %77 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %76 %uint_19 %int_1
+         %78 = OpCompositeExtract %v3float %value_1 1
+               OpStore %77 %78
+         %79 = OpCompositeExtract %uint %dest_1 0
+         %80 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %79 %uint_19 %int_2
+         %81 = OpCompositeExtract %v3float %value_1 2
+               OpStore %80 %81
+         %82 = OpCompositeExtract %uint %dest_1 0
+         %84 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %82 %uint_19 %int_3
+         %86 = OpCompositeExtract %v3float %value_1 3
+               OpStore %84 %86
                OpReturn
                OpFunctionEnd
-       %main = OpFunction %void None %152
-        %154 = OpLabel
-        %156 = OpLoad %uint %idx_1
-        %155 = OpFunctionCall %void %main_inner %156
+%assign_and_preserve_padding_3_sb_arr_X_arr2_vec3_f32 = OpFunction %void None %87
+     %dest_2 = OpFunctionParameter %_arr_uint_uint_1
+    %value_2 = OpFunctionParameter %_arr_v3float_uint_2
+         %91 = OpLabel
+          %i = OpVariable %_ptr_Function_uint Function %45
+%var_for_index = OpVariable %_ptr_Function__arr_v3float_uint_2 Function %106
+               OpStore %i %45
+               OpBranch %94
+         %94 = OpLabel
+               OpLoopMerge %95 %96 None
+               OpBranch %97
+         %97 = OpLabel
+         %99 = OpLoad %uint %i
+        %100 = OpULessThan %bool %99 %uint_2
+         %98 = OpLogicalNot %bool %100
+               OpSelectionMerge %102 None
+               OpBranchConditional %98 %103 %102
+        %103 = OpLabel
+               OpBranch %95
+        %102 = OpLabel
+               OpStore %var_for_index %value_2
+        %107 = OpCompositeExtract %uint %dest_2 0
+        %109 = OpLoad %uint %i
+        %110 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %107 %uint_21 %109
+        %111 = OpLoad %uint %i
+        %113 = OpAccessChain %_ptr_Function_v3float %var_for_index %111
+        %114 = OpLoad %v3float %113
+               OpStore %110 %114
+               OpBranch %96
+         %96 = OpLabel
+        %115 = OpLoad %uint %i
+        %116 = OpIAdd %uint %115 %uint_1
+               OpStore %i %116
+               OpBranch %94
+         %95 = OpLabel
+               OpReturn
+               OpFunctionEnd
+ %main_inner = OpFunction %void None %117
+        %idx = OpFunctionParameter %uint
+        %120 = OpLabel
+        %122 = OpAccessChain %_ptr_StorageBuffer_float %sb %uint_0 %idx %uint_0
+               OpStore %122 %123
+        %125 = OpAccessChain %_ptr_StorageBuffer_int %sb %uint_0 %idx %uint_1
+               OpStore %125 %40
+        %127 = OpAccessChain %_ptr_StorageBuffer_uint %sb %uint_0 %idx %uint_2
+               OpStore %127 %45
+        %129 = OpAccessChain %_ptr_StorageBuffer_v2float %sb %uint_0 %idx %uint_3
+               OpStore %129 %130
+        %133 = OpAccessChain %_ptr_StorageBuffer_v2int %sb %uint_0 %idx %uint_4
+               OpStore %133 %134
+        %137 = OpAccessChain %_ptr_StorageBuffer_v2uint %sb %uint_0 %idx %uint_5
+               OpStore %137 %138
+        %140 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %idx %uint_6
+               OpStore %140 %141
+        %144 = OpAccessChain %_ptr_StorageBuffer_v3int %sb %uint_0 %idx %uint_7
+               OpStore %144 %145
+        %148 = OpAccessChain %_ptr_StorageBuffer_v3uint %sb %uint_0 %idx %uint_8
+               OpStore %148 %149
+        %152 = OpAccessChain %_ptr_StorageBuffer_v4float %sb %uint_0 %idx %uint_9
+               OpStore %152 %153
+        %156 = OpAccessChain %_ptr_StorageBuffer_v4int %sb %uint_0 %idx %uint_10
+               OpStore %156 %157
+        %160 = OpAccessChain %_ptr_StorageBuffer_v4uint %sb %uint_0 %idx %uint_11
+               OpStore %160 %161
+        %164 = OpAccessChain %_ptr_StorageBuffer_mat2v2float %sb %uint_0 %idx %uint_12
+               OpStore %164 %165
+        %167 = OpCompositeConstruct %_arr_uint_uint_1 %idx
+        %166 = OpFunctionCall %void %assign_and_preserve_padding_sb_arr_X_mat2x3_f32 %167 %168
+        %171 = OpAccessChain %_ptr_StorageBuffer_mat2v4float %sb %uint_0 %idx %uint_14
+               OpStore %171 %172
+        %175 = OpAccessChain %_ptr_StorageBuffer_mat3v2float %sb %uint_0 %idx %uint_15
+               OpStore %175 %176
+        %177 = OpFunctionCall %void %assign_and_preserve_padding_1_sb_arr_X_mat3x3_f32 %167 %178
+        %181 = OpAccessChain %_ptr_StorageBuffer_mat3v4float %sb %uint_0 %idx %uint_17
+               OpStore %181 %182
+        %185 = OpAccessChain %_ptr_StorageBuffer_mat4v2float %sb %uint_0 %idx %uint_18
+               OpStore %185 %186
+        %187 = OpFunctionCall %void %assign_and_preserve_padding_2_sb_arr_X_mat4x3_f32 %167 %188
+        %191 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %sb %uint_0 %idx %uint_20
+               OpStore %191 %192
+        %193 = OpFunctionCall %void %assign_and_preserve_padding_3_sb_arr_X_arr2_vec3_f32 %167 %106
+               OpReturn
+               OpFunctionEnd
+       %main = OpFunction %void None %194
+        %196 = OpLabel
+        %198 = OpLoad %uint %idx_1
+        %197 = OpFunctionCall %void %main_inner %198
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.glsl b/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.glsl
index ab676c8..75dd6dd 100644
--- a/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.glsl
+++ b/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.glsl
@@ -57,7 +57,43 @@
   Inner arr[];
 } sb;
 
-void assign_and_preserve_padding_sb_arr_X_arr2_vec3_f32(uint dest[1], vec3 value[2]) {
+void assign_and_preserve_padding_sb_arr_X_mat2x3_f32(uint dest[1], mat2x3 value) {
+  sb.arr[dest[0]].mat2x3_f32[0] = value[0u];
+  sb.arr[dest[0]].mat2x3_f32[1] = value[1u];
+}
+
+void assign_and_preserve_padding_1_sb_arr_X_mat3x3_f32(uint dest[1], mat3 value) {
+  sb.arr[dest[0]].mat3x3_f32[0] = value[0u];
+  sb.arr[dest[0]].mat3x3_f32[1] = value[1u];
+  sb.arr[dest[0]].mat3x3_f32[2] = value[2u];
+}
+
+void assign_and_preserve_padding_2_sb_arr_X_mat4x3_f32(uint dest[1], mat4x3 value) {
+  sb.arr[dest[0]].mat4x3_f32[0] = value[0u];
+  sb.arr[dest[0]].mat4x3_f32[1] = value[1u];
+  sb.arr[dest[0]].mat4x3_f32[2] = value[2u];
+  sb.arr[dest[0]].mat4x3_f32[3] = value[3u];
+}
+
+void assign_and_preserve_padding_3_sb_arr_X_mat2x3_f16(uint dest[1], f16mat2x3 value) {
+  sb.arr[dest[0]].mat2x3_f16[0] = value[0u];
+  sb.arr[dest[0]].mat2x3_f16[1] = value[1u];
+}
+
+void assign_and_preserve_padding_4_sb_arr_X_mat3x3_f16(uint dest[1], f16mat3 value) {
+  sb.arr[dest[0]].mat3x3_f16[0] = value[0u];
+  sb.arr[dest[0]].mat3x3_f16[1] = value[1u];
+  sb.arr[dest[0]].mat3x3_f16[2] = value[2u];
+}
+
+void assign_and_preserve_padding_5_sb_arr_X_mat4x3_f16(uint dest[1], f16mat4x3 value) {
+  sb.arr[dest[0]].mat4x3_f16[0] = value[0u];
+  sb.arr[dest[0]].mat4x3_f16[1] = value[1u];
+  sb.arr[dest[0]].mat4x3_f16[2] = value[2u];
+  sb.arr[dest[0]].mat4x3_f16[3] = value[3u];
+}
+
+void assign_and_preserve_padding_6_sb_arr_X_arr2_vec3_f32(uint dest[1], vec3 value[2]) {
   {
     for(uint i = 0u; (i < 2u); i = (i + 1u)) {
       sb.arr[dest[0]].arr2_vec3_f32[i] = value[i];
@@ -83,28 +119,34 @@
   sb.arr[idx].vec4_u32 = uvec4(0u);
   sb.arr[idx].vec4_f16 = f16vec4(0.0hf);
   sb.arr[idx].mat2x2_f32 = mat2(vec2(0.0f), vec2(0.0f));
-  sb.arr[idx].mat2x3_f32 = mat2x3(vec3(0.0f), vec3(0.0f));
+  uint tint_symbol_1[1] = uint[1](idx);
+  assign_and_preserve_padding_sb_arr_X_mat2x3_f32(tint_symbol_1, mat2x3(vec3(0.0f), vec3(0.0f)));
   sb.arr[idx].mat2x4_f32 = mat2x4(vec4(0.0f), vec4(0.0f));
   sb.arr[idx].mat3x2_f32 = mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f));
-  sb.arr[idx].mat3x3_f32 = mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f));
+  uint tint_symbol_2[1] = uint[1](idx);
+  assign_and_preserve_padding_1_sb_arr_X_mat3x3_f32(tint_symbol_2, mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f)));
   sb.arr[idx].mat3x4_f32 = mat3x4(vec4(0.0f), vec4(0.0f), vec4(0.0f));
   sb.arr[idx].mat4x2_f32 = mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f));
-  sb.arr[idx].mat4x3_f32 = mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f));
+  uint tint_symbol_3[1] = uint[1](idx);
+  assign_and_preserve_padding_2_sb_arr_X_mat4x3_f32(tint_symbol_3, mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f)));
   sb.arr[idx].mat4x4_f32 = mat4(vec4(0.0f), vec4(0.0f), vec4(0.0f), vec4(0.0f));
   sb.arr[idx].mat2x2_f16 = f16mat2(f16vec2(0.0hf), f16vec2(0.0hf));
-  sb.arr[idx].mat2x3_f16 = f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf));
+  uint tint_symbol_4[1] = uint[1](idx);
+  assign_and_preserve_padding_3_sb_arr_X_mat2x3_f16(tint_symbol_4, f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf)));
   sb.arr[idx].mat2x4_f16 = f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf));
   sb.arr[idx].mat3x2_f16 = f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf));
-  sb.arr[idx].mat3x3_f16 = f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf));
+  uint tint_symbol_5[1] = uint[1](idx);
+  assign_and_preserve_padding_4_sb_arr_X_mat3x3_f16(tint_symbol_5, f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf)));
   sb.arr[idx].mat3x4_f16 = f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf));
   sb.arr[idx].mat4x2_f16 = f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf));
-  sb.arr[idx].mat4x3_f16 = f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf));
+  uint tint_symbol_6[1] = uint[1](idx);
+  assign_and_preserve_padding_5_sb_arr_X_mat4x3_f16(tint_symbol_6, f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf)));
   sb.arr[idx].mat4x4_f16 = f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf));
-  uint tint_symbol_1[1] = uint[1](idx);
-  vec3 tint_symbol_2[2] = vec3[2](vec3(0.0f), vec3(0.0f));
-  assign_and_preserve_padding_sb_arr_X_arr2_vec3_f32(tint_symbol_1, tint_symbol_2);
-  f16mat4x2 tint_symbol_3[2] = f16mat4x2[2](f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf)), f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf)));
-  sb.arr[idx].arr2_mat4x2_f16 = tint_symbol_3;
+  uint tint_symbol_7[1] = uint[1](idx);
+  vec3 tint_symbol_8[2] = vec3[2](vec3(0.0f), vec3(0.0f));
+  assign_and_preserve_padding_6_sb_arr_X_arr2_vec3_f32(tint_symbol_7, tint_symbol_8);
+  f16mat4x2 tint_symbol_9[2] = f16mat4x2[2](f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf)), f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf)));
+  sb.arr[idx].arr2_mat4x2_f16 = tint_symbol_9;
 }
 
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.msl b/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.msl
index 6f09850..d38aab3 100644
--- a/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.msl
+++ b/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.msl
@@ -67,7 +67,43 @@
   /* 0x0000 */ tint_array<Inner, 1> arr;
 };
 
-void assign_and_preserve_padding(device tint_array<float3, 2>* const dest, tint_array<float3, 2> value) {
+void assign_and_preserve_padding(device float2x3* const dest, float2x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+}
+
+void assign_and_preserve_padding_1(device float3x3* const dest, float3x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+}
+
+void assign_and_preserve_padding_2(device float4x3* const dest, float4x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+  (*(dest))[3u] = value[3u];
+}
+
+void assign_and_preserve_padding_3(device half2x3* const dest, half2x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+}
+
+void assign_and_preserve_padding_4(device half3x3* const dest, half3x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+}
+
+void assign_and_preserve_padding_5(device half4x3* const dest, half4x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+  (*(dest))[3u] = value[3u];
+}
+
+void assign_and_preserve_padding_6(device tint_array<float3, 2>* const dest, tint_array<float3, 2> value) {
   for(uint i = 0u; (i < 2u); i = (i + 1u)) {
     (*(dest))[i] = value[i];
   }
@@ -91,25 +127,25 @@
   (*(tint_symbol_3)).arr[idx].vec4_u32 = uint4(0u);
   (*(tint_symbol_3)).arr[idx].vec4_f16 = half4(0.0h);
   (*(tint_symbol_3)).arr[idx].mat2x2_f32 = float2x2(float2(0.0f), float2(0.0f));
-  (*(tint_symbol_3)).arr[idx].mat2x3_f32 = float2x3(float3(0.0f), float3(0.0f));
+  assign_and_preserve_padding(&((*(tint_symbol_3)).arr[idx].mat2x3_f32), float2x3(float3(0.0f), float3(0.0f)));
   (*(tint_symbol_3)).arr[idx].mat2x4_f32 = float2x4(float4(0.0f), float4(0.0f));
   (*(tint_symbol_3)).arr[idx].mat3x2_f32 = float3x2(float2(0.0f), float2(0.0f), float2(0.0f));
-  (*(tint_symbol_3)).arr[idx].mat3x3_f32 = float3x3(float3(0.0f), float3(0.0f), float3(0.0f));
+  assign_and_preserve_padding_1(&((*(tint_symbol_3)).arr[idx].mat3x3_f32), float3x3(float3(0.0f), float3(0.0f), float3(0.0f)));
   (*(tint_symbol_3)).arr[idx].mat3x4_f32 = float3x4(float4(0.0f), float4(0.0f), float4(0.0f));
   (*(tint_symbol_3)).arr[idx].mat4x2_f32 = float4x2(float2(0.0f), float2(0.0f), float2(0.0f), float2(0.0f));
-  (*(tint_symbol_3)).arr[idx].mat4x3_f32 = float4x3(float3(0.0f), float3(0.0f), float3(0.0f), float3(0.0f));
+  assign_and_preserve_padding_2(&((*(tint_symbol_3)).arr[idx].mat4x3_f32), float4x3(float3(0.0f), float3(0.0f), float3(0.0f), float3(0.0f)));
   (*(tint_symbol_3)).arr[idx].mat4x4_f32 = float4x4(float4(0.0f), float4(0.0f), float4(0.0f), float4(0.0f));
   (*(tint_symbol_3)).arr[idx].mat2x2_f16 = half2x2(half2(0.0h), half2(0.0h));
-  (*(tint_symbol_3)).arr[idx].mat2x3_f16 = half2x3(half3(0.0h), half3(0.0h));
+  assign_and_preserve_padding_3(&((*(tint_symbol_3)).arr[idx].mat2x3_f16), half2x3(half3(0.0h), half3(0.0h)));
   (*(tint_symbol_3)).arr[idx].mat2x4_f16 = half2x4(half4(0.0h), half4(0.0h));
   (*(tint_symbol_3)).arr[idx].mat3x2_f16 = half3x2(half2(0.0h), half2(0.0h), half2(0.0h));
-  (*(tint_symbol_3)).arr[idx].mat3x3_f16 = half3x3(half3(0.0h), half3(0.0h), half3(0.0h));
+  assign_and_preserve_padding_4(&((*(tint_symbol_3)).arr[idx].mat3x3_f16), half3x3(half3(0.0h), half3(0.0h), half3(0.0h)));
   (*(tint_symbol_3)).arr[idx].mat3x4_f16 = half3x4(half4(0.0h), half4(0.0h), half4(0.0h));
   (*(tint_symbol_3)).arr[idx].mat4x2_f16 = half4x2(half2(0.0h), half2(0.0h), half2(0.0h), half2(0.0h));
-  (*(tint_symbol_3)).arr[idx].mat4x3_f16 = half4x3(half3(0.0h), half3(0.0h), half3(0.0h), half3(0.0h));
+  assign_and_preserve_padding_5(&((*(tint_symbol_3)).arr[idx].mat4x3_f16), half4x3(half3(0.0h), half3(0.0h), half3(0.0h), half3(0.0h)));
   (*(tint_symbol_3)).arr[idx].mat4x4_f16 = half4x4(half4(0.0h), half4(0.0h), half4(0.0h), half4(0.0h));
   tint_array<float3, 2> const tint_symbol_1 = tint_array<float3, 2>{};
-  assign_and_preserve_padding(&((*(tint_symbol_3)).arr[idx].arr2_vec3_f32), tint_symbol_1);
+  assign_and_preserve_padding_6(&((*(tint_symbol_3)).arr[idx].arr2_vec3_f32), tint_symbol_1);
   tint_array<half4x2, 2> const tint_symbol_2 = tint_array<half4x2, 2>{};
   (*(tint_symbol_3)).arr[idx].arr2_mat4x2_f16 = tint_symbol_2;
 }
diff --git a/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.spvasm b/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.spvasm
index a1c3bcb..491802b 100644
--- a/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.spvasm
+++ b/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 227
+; Bound: 308
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -52,9 +52,27 @@
                OpMemberName %Inner 34 "arr2_vec3_f32"
                OpMemberName %Inner 35 "arr2_mat4x2_f16"
                OpName %sb "sb"
-               OpName %assign_and_preserve_padding_sb_arr_X_arr2_vec3_f32 "assign_and_preserve_padding_sb_arr_X_arr2_vec3_f32"
+               OpName %assign_and_preserve_padding_sb_arr_X_mat2x3_f32 "assign_and_preserve_padding_sb_arr_X_mat2x3_f32"
                OpName %dest "dest"
                OpName %value "value"
+               OpName %assign_and_preserve_padding_1_sb_arr_X_mat3x3_f32 "assign_and_preserve_padding_1_sb_arr_X_mat3x3_f32"
+               OpName %dest_0 "dest"
+               OpName %value_0 "value"
+               OpName %assign_and_preserve_padding_2_sb_arr_X_mat4x3_f32 "assign_and_preserve_padding_2_sb_arr_X_mat4x3_f32"
+               OpName %dest_1 "dest"
+               OpName %value_1 "value"
+               OpName %assign_and_preserve_padding_3_sb_arr_X_mat2x3_f16 "assign_and_preserve_padding_3_sb_arr_X_mat2x3_f16"
+               OpName %dest_2 "dest"
+               OpName %value_2 "value"
+               OpName %assign_and_preserve_padding_4_sb_arr_X_mat3x3_f16 "assign_and_preserve_padding_4_sb_arr_X_mat3x3_f16"
+               OpName %dest_3 "dest"
+               OpName %value_3 "value"
+               OpName %assign_and_preserve_padding_5_sb_arr_X_mat4x3_f16 "assign_and_preserve_padding_5_sb_arr_X_mat4x3_f16"
+               OpName %dest_4 "dest"
+               OpName %value_4 "value"
+               OpName %assign_and_preserve_padding_6_sb_arr_X_arr2_vec3_f32 "assign_and_preserve_padding_6_sb_arr_X_arr2_vec3_f32"
+               OpName %dest_5 "dest"
+               OpName %value_5 "value"
                OpName %i "i"
                OpName %var_for_index "var_for_index"
                OpName %main_inner "main_inner"
@@ -190,235 +208,340 @@
        %void = OpTypeVoid
      %uint_1 = OpConstant %uint 1
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
-         %45 = OpTypeFunction %void %_arr_uint_uint_1 %_arr_v3float_uint_2
-         %53 = OpConstantNull %uint
+         %45 = OpTypeFunction %void %_arr_uint_uint_1 %mat2v3float
+     %uint_0 = OpConstant %uint 0
+         %54 = OpConstantNull %int
+    %uint_17 = OpConstant %uint 17
+%_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
+         %59 = OpConstantNull %uint
+      %int_1 = OpConstant %int 1
+         %65 = OpTypeFunction %void %_arr_uint_uint_1 %mat3v3float
+    %uint_20 = OpConstant %uint 20
+      %int_2 = OpConstant %int 2
+         %81 = OpTypeFunction %void %_arr_uint_uint_1 %mat4v3float
+    %uint_23 = OpConstant %uint 23
+      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
+        %101 = OpTypeFunction %void %_arr_uint_uint_1 %mat2v3half
+    %uint_26 = OpConstant %uint 26
+%_ptr_StorageBuffer_v3half = OpTypePointer StorageBuffer %v3half
+        %114 = OpTypeFunction %void %_arr_uint_uint_1 %mat3v3half
+    %uint_29 = OpConstant %uint 29
+        %129 = OpTypeFunction %void %_arr_uint_uint_1 %mat4v3half
+    %uint_32 = OpConstant %uint 32
+        %147 = OpTypeFunction %void %_arr_uint_uint_1 %_arr_v3float_uint_2
 %_ptr_Function_uint = OpTypePointer Function %uint
        %bool = OpTypeBool
 %_ptr_Function__arr_v3float_uint_2 = OpTypePointer Function %_arr_v3float_uint_2
-         %68 = OpConstantNull %_arr_v3float_uint_2
-     %uint_0 = OpConstant %uint 0
-         %70 = OpConstantNull %int
+        %166 = OpConstantNull %_arr_v3float_uint_2
     %uint_34 = OpConstant %uint 34
-%_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
 %_ptr_Function_v3float = OpTypePointer Function %v3float
-         %82 = OpTypeFunction %void %uint
+        %177 = OpTypeFunction %void %uint
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-         %88 = OpConstantNull %float
+        %183 = OpConstantNull %float
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-     %uint_3 = OpConstant %uint 3
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
-         %96 = OpConstantNull %half
+        %190 = OpConstantNull %half
      %uint_4 = OpConstant %uint 4
 %_ptr_StorageBuffer_v2float = OpTypePointer StorageBuffer %v2float
-        %100 = OpConstantNull %v2float
+        %194 = OpConstantNull %v2float
      %uint_5 = OpConstant %uint 5
 %_ptr_StorageBuffer_v2int = OpTypePointer StorageBuffer %v2int
-        %104 = OpConstantNull %v2int
+        %198 = OpConstantNull %v2int
      %uint_6 = OpConstant %uint 6
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
-        %108 = OpConstantNull %v2uint
+        %202 = OpConstantNull %v2uint
      %uint_7 = OpConstant %uint 7
 %_ptr_StorageBuffer_v2half = OpTypePointer StorageBuffer %v2half
-        %112 = OpConstantNull %v2half
+        %206 = OpConstantNull %v2half
      %uint_8 = OpConstant %uint 8
-        %115 = OpConstantNull %v3float
+        %209 = OpConstantNull %v3float
      %uint_9 = OpConstant %uint 9
 %_ptr_StorageBuffer_v3int = OpTypePointer StorageBuffer %v3int
-        %119 = OpConstantNull %v3int
+        %213 = OpConstantNull %v3int
     %uint_10 = OpConstant %uint 10
 %_ptr_StorageBuffer_v3uint = OpTypePointer StorageBuffer %v3uint
-        %123 = OpConstantNull %v3uint
+        %217 = OpConstantNull %v3uint
     %uint_11 = OpConstant %uint 11
-%_ptr_StorageBuffer_v3half = OpTypePointer StorageBuffer %v3half
-        %127 = OpConstantNull %v3half
+        %220 = OpConstantNull %v3half
     %uint_12 = OpConstant %uint 12
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-        %131 = OpConstantNull %v4float
+        %224 = OpConstantNull %v4float
     %uint_13 = OpConstant %uint 13
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-        %135 = OpConstantNull %v4int
+        %228 = OpConstantNull %v4int
     %uint_14 = OpConstant %uint 14
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
-        %139 = OpConstantNull %v4uint
+        %232 = OpConstantNull %v4uint
     %uint_15 = OpConstant %uint 15
 %_ptr_StorageBuffer_v4half = OpTypePointer StorageBuffer %v4half
-        %143 = OpConstantNull %v4half
+        %236 = OpConstantNull %v4half
     %uint_16 = OpConstant %uint 16
 %_ptr_StorageBuffer_mat2v2float = OpTypePointer StorageBuffer %mat2v2float
-        %147 = OpConstantNull %mat2v2float
-    %uint_17 = OpConstant %uint 17
-%_ptr_StorageBuffer_mat2v3float = OpTypePointer StorageBuffer %mat2v3float
-        %151 = OpConstantNull %mat2v3float
+        %240 = OpConstantNull %mat2v2float
+        %243 = OpConstantNull %mat2v3float
     %uint_18 = OpConstant %uint 18
 %_ptr_StorageBuffer_mat2v4float = OpTypePointer StorageBuffer %mat2v4float
-        %155 = OpConstantNull %mat2v4float
+        %247 = OpConstantNull %mat2v4float
     %uint_19 = OpConstant %uint 19
 %_ptr_StorageBuffer_mat3v2float = OpTypePointer StorageBuffer %mat3v2float
-        %159 = OpConstantNull %mat3v2float
-    %uint_20 = OpConstant %uint 20
-%_ptr_StorageBuffer_mat3v3float = OpTypePointer StorageBuffer %mat3v3float
-        %163 = OpConstantNull %mat3v3float
+        %251 = OpConstantNull %mat3v2float
+        %253 = OpConstantNull %mat3v3float
     %uint_21 = OpConstant %uint 21
 %_ptr_StorageBuffer_mat3v4float = OpTypePointer StorageBuffer %mat3v4float
-        %167 = OpConstantNull %mat3v4float
+        %257 = OpConstantNull %mat3v4float
     %uint_22 = OpConstant %uint 22
 %_ptr_StorageBuffer_mat4v2float = OpTypePointer StorageBuffer %mat4v2float
-        %171 = OpConstantNull %mat4v2float
-    %uint_23 = OpConstant %uint 23
-%_ptr_StorageBuffer_mat4v3float = OpTypePointer StorageBuffer %mat4v3float
-        %175 = OpConstantNull %mat4v3float
+        %261 = OpConstantNull %mat4v2float
+        %263 = OpConstantNull %mat4v3float
     %uint_24 = OpConstant %uint 24
 %_ptr_StorageBuffer_mat4v4float = OpTypePointer StorageBuffer %mat4v4float
-        %179 = OpConstantNull %mat4v4float
+        %267 = OpConstantNull %mat4v4float
     %uint_25 = OpConstant %uint 25
 %_ptr_StorageBuffer_mat2v2half = OpTypePointer StorageBuffer %mat2v2half
-        %183 = OpConstantNull %mat2v2half
-    %uint_26 = OpConstant %uint 26
-%_ptr_StorageBuffer_mat2v3half = OpTypePointer StorageBuffer %mat2v3half
-        %187 = OpConstantNull %mat2v3half
+        %271 = OpConstantNull %mat2v2half
+        %273 = OpConstantNull %mat2v3half
     %uint_27 = OpConstant %uint 27
 %_ptr_StorageBuffer_mat2v4half = OpTypePointer StorageBuffer %mat2v4half
-        %191 = OpConstantNull %mat2v4half
+        %277 = OpConstantNull %mat2v4half
     %uint_28 = OpConstant %uint 28
 %_ptr_StorageBuffer_mat3v2half = OpTypePointer StorageBuffer %mat3v2half
-        %195 = OpConstantNull %mat3v2half
-    %uint_29 = OpConstant %uint 29
-%_ptr_StorageBuffer_mat3v3half = OpTypePointer StorageBuffer %mat3v3half
-        %199 = OpConstantNull %mat3v3half
+        %281 = OpConstantNull %mat3v2half
+        %283 = OpConstantNull %mat3v3half
     %uint_30 = OpConstant %uint 30
 %_ptr_StorageBuffer_mat3v4half = OpTypePointer StorageBuffer %mat3v4half
-        %203 = OpConstantNull %mat3v4half
+        %287 = OpConstantNull %mat3v4half
     %uint_31 = OpConstant %uint 31
 %_ptr_StorageBuffer_mat4v2half = OpTypePointer StorageBuffer %mat4v2half
-        %207 = OpConstantNull %mat4v2half
-    %uint_32 = OpConstant %uint 32
-%_ptr_StorageBuffer_mat4v3half = OpTypePointer StorageBuffer %mat4v3half
-        %211 = OpConstantNull %mat4v3half
+        %291 = OpConstantNull %mat4v2half
+        %293 = OpConstantNull %mat4v3half
     %uint_33 = OpConstant %uint 33
 %_ptr_StorageBuffer_mat4v4half = OpTypePointer StorageBuffer %mat4v4half
-        %215 = OpConstantNull %mat4v4half
+        %297 = OpConstantNull %mat4v4half
     %uint_35 = OpConstant %uint 35
 %_ptr_StorageBuffer__arr_mat4v2half_uint_2 = OpTypePointer StorageBuffer %_arr_mat4v2half_uint_2
-        %221 = OpConstantNull %_arr_mat4v2half_uint_2
-        %222 = OpTypeFunction %void
-%assign_and_preserve_padding_sb_arr_X_arr2_vec3_f32 = OpFunction %void None %45
+        %302 = OpConstantNull %_arr_mat4v2half_uint_2
+        %303 = OpTypeFunction %void
+%assign_and_preserve_padding_sb_arr_X_mat2x3_f32 = OpFunction %void None %45
        %dest = OpFunctionParameter %_arr_uint_uint_1
-      %value = OpFunctionParameter %_arr_v3float_uint_2
+      %value = OpFunctionParameter %mat2v3float
          %52 = OpLabel
-          %i = OpVariable %_ptr_Function_uint Function %53
-%var_for_index = OpVariable %_ptr_Function__arr_v3float_uint_2 Function %68
-               OpStore %i %53
-               OpBranch %56
-         %56 = OpLabel
-               OpLoopMerge %57 %58 None
-               OpBranch %59
-         %59 = OpLabel
-         %61 = OpLoad %uint %i
-         %62 = OpULessThan %bool %61 %uint_2
-         %60 = OpLogicalNot %bool %62
-               OpSelectionMerge %64 None
-               OpBranchConditional %60 %65 %64
-         %65 = OpLabel
-               OpBranch %57
-         %64 = OpLabel
-               OpStore %var_for_index %value
-         %71 = OpCompositeExtract %uint %dest 0
-         %73 = OpLoad %uint %i
-         %75 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %71 %uint_34 %73
-         %76 = OpLoad %uint %i
-         %78 = OpAccessChain %_ptr_Function_v3float %var_for_index %76
-         %79 = OpLoad %v3float %78
-               OpStore %75 %79
-               OpBranch %58
-         %58 = OpLabel
-         %80 = OpLoad %uint %i
-         %81 = OpIAdd %uint %80 %uint_1
-               OpStore %i %81
-               OpBranch %56
-         %57 = OpLabel
+         %55 = OpCompositeExtract %uint %dest 0
+         %58 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %55 %uint_17 %54
+         %60 = OpCompositeExtract %v3float %value 0
+               OpStore %58 %60
+         %61 = OpCompositeExtract %uint %dest 0
+         %63 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %61 %uint_17 %int_1
+         %64 = OpCompositeExtract %v3float %value 1
+               OpStore %63 %64
                OpReturn
                OpFunctionEnd
- %main_inner = OpFunction %void None %82
-        %idx = OpFunctionParameter %uint
+%assign_and_preserve_padding_1_sb_arr_X_mat3x3_f32 = OpFunction %void None %65
+     %dest_0 = OpFunctionParameter %_arr_uint_uint_1
+    %value_0 = OpFunctionParameter %mat3v3float
+         %69 = OpLabel
+         %70 = OpCompositeExtract %uint %dest_0 0
+         %72 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %70 %uint_20 %54
+         %73 = OpCompositeExtract %v3float %value_0 0
+               OpStore %72 %73
+         %74 = OpCompositeExtract %uint %dest_0 0
+         %75 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %74 %uint_20 %int_1
+         %76 = OpCompositeExtract %v3float %value_0 1
+               OpStore %75 %76
+         %77 = OpCompositeExtract %uint %dest_0 0
+         %79 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %77 %uint_20 %int_2
+         %80 = OpCompositeExtract %v3float %value_0 2
+               OpStore %79 %80
+               OpReturn
+               OpFunctionEnd
+%assign_and_preserve_padding_2_sb_arr_X_mat4x3_f32 = OpFunction %void None %81
+     %dest_1 = OpFunctionParameter %_arr_uint_uint_1
+    %value_1 = OpFunctionParameter %mat4v3float
          %85 = OpLabel
-         %87 = OpAccessChain %_ptr_StorageBuffer_float %sb %uint_0 %idx %uint_0
-               OpStore %87 %88
-         %90 = OpAccessChain %_ptr_StorageBuffer_int %sb %uint_0 %idx %uint_1
-               OpStore %90 %70
-         %92 = OpAccessChain %_ptr_StorageBuffer_uint %sb %uint_0 %idx %uint_2
-               OpStore %92 %53
-         %95 = OpAccessChain %_ptr_StorageBuffer_half %sb %uint_0 %idx %uint_3
-               OpStore %95 %96
-         %99 = OpAccessChain %_ptr_StorageBuffer_v2float %sb %uint_0 %idx %uint_4
-               OpStore %99 %100
-        %103 = OpAccessChain %_ptr_StorageBuffer_v2int %sb %uint_0 %idx %uint_5
-               OpStore %103 %104
-        %107 = OpAccessChain %_ptr_StorageBuffer_v2uint %sb %uint_0 %idx %uint_6
-               OpStore %107 %108
-        %111 = OpAccessChain %_ptr_StorageBuffer_v2half %sb %uint_0 %idx %uint_7
-               OpStore %111 %112
-        %114 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %idx %uint_8
-               OpStore %114 %115
-        %118 = OpAccessChain %_ptr_StorageBuffer_v3int %sb %uint_0 %idx %uint_9
-               OpStore %118 %119
-        %122 = OpAccessChain %_ptr_StorageBuffer_v3uint %sb %uint_0 %idx %uint_10
-               OpStore %122 %123
-        %126 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %idx %uint_11
-               OpStore %126 %127
-        %130 = OpAccessChain %_ptr_StorageBuffer_v4float %sb %uint_0 %idx %uint_12
-               OpStore %130 %131
-        %134 = OpAccessChain %_ptr_StorageBuffer_v4int %sb %uint_0 %idx %uint_13
-               OpStore %134 %135
-        %138 = OpAccessChain %_ptr_StorageBuffer_v4uint %sb %uint_0 %idx %uint_14
-               OpStore %138 %139
-        %142 = OpAccessChain %_ptr_StorageBuffer_v4half %sb %uint_0 %idx %uint_15
-               OpStore %142 %143
-        %146 = OpAccessChain %_ptr_StorageBuffer_mat2v2float %sb %uint_0 %idx %uint_16
-               OpStore %146 %147
-        %150 = OpAccessChain %_ptr_StorageBuffer_mat2v3float %sb %uint_0 %idx %uint_17
-               OpStore %150 %151
-        %154 = OpAccessChain %_ptr_StorageBuffer_mat2v4float %sb %uint_0 %idx %uint_18
-               OpStore %154 %155
-        %158 = OpAccessChain %_ptr_StorageBuffer_mat3v2float %sb %uint_0 %idx %uint_19
-               OpStore %158 %159
-        %162 = OpAccessChain %_ptr_StorageBuffer_mat3v3float %sb %uint_0 %idx %uint_20
-               OpStore %162 %163
-        %166 = OpAccessChain %_ptr_StorageBuffer_mat3v4float %sb %uint_0 %idx %uint_21
-               OpStore %166 %167
-        %170 = OpAccessChain %_ptr_StorageBuffer_mat4v2float %sb %uint_0 %idx %uint_22
-               OpStore %170 %171
-        %174 = OpAccessChain %_ptr_StorageBuffer_mat4v3float %sb %uint_0 %idx %uint_23
-               OpStore %174 %175
-        %178 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %sb %uint_0 %idx %uint_24
-               OpStore %178 %179
-        %182 = OpAccessChain %_ptr_StorageBuffer_mat2v2half %sb %uint_0 %idx %uint_25
-               OpStore %182 %183
-        %186 = OpAccessChain %_ptr_StorageBuffer_mat2v3half %sb %uint_0 %idx %uint_26
-               OpStore %186 %187
-        %190 = OpAccessChain %_ptr_StorageBuffer_mat2v4half %sb %uint_0 %idx %uint_27
-               OpStore %190 %191
-        %194 = OpAccessChain %_ptr_StorageBuffer_mat3v2half %sb %uint_0 %idx %uint_28
-               OpStore %194 %195
-        %198 = OpAccessChain %_ptr_StorageBuffer_mat3v3half %sb %uint_0 %idx %uint_29
-               OpStore %198 %199
-        %202 = OpAccessChain %_ptr_StorageBuffer_mat3v4half %sb %uint_0 %idx %uint_30
-               OpStore %202 %203
-        %206 = OpAccessChain %_ptr_StorageBuffer_mat4v2half %sb %uint_0 %idx %uint_31
-               OpStore %206 %207
-        %210 = OpAccessChain %_ptr_StorageBuffer_mat4v3half %sb %uint_0 %idx %uint_32
-               OpStore %210 %211
-        %214 = OpAccessChain %_ptr_StorageBuffer_mat4v4half %sb %uint_0 %idx %uint_33
-               OpStore %214 %215
-        %217 = OpCompositeConstruct %_arr_uint_uint_1 %idx
-        %216 = OpFunctionCall %void %assign_and_preserve_padding_sb_arr_X_arr2_vec3_f32 %217 %68
-        %220 = OpAccessChain %_ptr_StorageBuffer__arr_mat4v2half_uint_2 %sb %uint_0 %idx %uint_35
-               OpStore %220 %221
+         %86 = OpCompositeExtract %uint %dest_1 0
+         %88 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %86 %uint_23 %54
+         %89 = OpCompositeExtract %v3float %value_1 0
+               OpStore %88 %89
+         %90 = OpCompositeExtract %uint %dest_1 0
+         %91 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %90 %uint_23 %int_1
+         %92 = OpCompositeExtract %v3float %value_1 1
+               OpStore %91 %92
+         %93 = OpCompositeExtract %uint %dest_1 0
+         %94 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %93 %uint_23 %int_2
+         %95 = OpCompositeExtract %v3float %value_1 2
+               OpStore %94 %95
+         %96 = OpCompositeExtract %uint %dest_1 0
+         %98 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %96 %uint_23 %int_3
+        %100 = OpCompositeExtract %v3float %value_1 3
+               OpStore %98 %100
                OpReturn
                OpFunctionEnd
-       %main = OpFunction %void None %222
-        %224 = OpLabel
-        %226 = OpLoad %uint %idx_1
-        %225 = OpFunctionCall %void %main_inner %226
+%assign_and_preserve_padding_3_sb_arr_X_mat2x3_f16 = OpFunction %void None %101
+     %dest_2 = OpFunctionParameter %_arr_uint_uint_1
+    %value_2 = OpFunctionParameter %mat2v3half
+        %105 = OpLabel
+        %106 = OpCompositeExtract %uint %dest_2 0
+        %109 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %106 %uint_26 %54
+        %110 = OpCompositeExtract %v3half %value_2 0
+               OpStore %109 %110
+        %111 = OpCompositeExtract %uint %dest_2 0
+        %112 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %111 %uint_26 %int_1
+        %113 = OpCompositeExtract %v3half %value_2 1
+               OpStore %112 %113
+               OpReturn
+               OpFunctionEnd
+%assign_and_preserve_padding_4_sb_arr_X_mat3x3_f16 = OpFunction %void None %114
+     %dest_3 = OpFunctionParameter %_arr_uint_uint_1
+    %value_3 = OpFunctionParameter %mat3v3half
+        %118 = OpLabel
+        %119 = OpCompositeExtract %uint %dest_3 0
+        %121 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %119 %uint_29 %54
+        %122 = OpCompositeExtract %v3half %value_3 0
+               OpStore %121 %122
+        %123 = OpCompositeExtract %uint %dest_3 0
+        %124 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %123 %uint_29 %int_1
+        %125 = OpCompositeExtract %v3half %value_3 1
+               OpStore %124 %125
+        %126 = OpCompositeExtract %uint %dest_3 0
+        %127 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %126 %uint_29 %int_2
+        %128 = OpCompositeExtract %v3half %value_3 2
+               OpStore %127 %128
+               OpReturn
+               OpFunctionEnd
+%assign_and_preserve_padding_5_sb_arr_X_mat4x3_f16 = OpFunction %void None %129
+     %dest_4 = OpFunctionParameter %_arr_uint_uint_1
+    %value_4 = OpFunctionParameter %mat4v3half
+        %133 = OpLabel
+        %134 = OpCompositeExtract %uint %dest_4 0
+        %136 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %134 %uint_32 %54
+        %137 = OpCompositeExtract %v3half %value_4 0
+               OpStore %136 %137
+        %138 = OpCompositeExtract %uint %dest_4 0
+        %139 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %138 %uint_32 %int_1
+        %140 = OpCompositeExtract %v3half %value_4 1
+               OpStore %139 %140
+        %141 = OpCompositeExtract %uint %dest_4 0
+        %142 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %141 %uint_32 %int_2
+        %143 = OpCompositeExtract %v3half %value_4 2
+               OpStore %142 %143
+        %144 = OpCompositeExtract %uint %dest_4 0
+        %145 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %144 %uint_32 %int_3
+        %146 = OpCompositeExtract %v3half %value_4 3
+               OpStore %145 %146
+               OpReturn
+               OpFunctionEnd
+%assign_and_preserve_padding_6_sb_arr_X_arr2_vec3_f32 = OpFunction %void None %147
+     %dest_5 = OpFunctionParameter %_arr_uint_uint_1
+    %value_5 = OpFunctionParameter %_arr_v3float_uint_2
+        %151 = OpLabel
+          %i = OpVariable %_ptr_Function_uint Function %59
+%var_for_index = OpVariable %_ptr_Function__arr_v3float_uint_2 Function %166
+               OpStore %i %59
+               OpBranch %154
+        %154 = OpLabel
+               OpLoopMerge %155 %156 None
+               OpBranch %157
+        %157 = OpLabel
+        %159 = OpLoad %uint %i
+        %160 = OpULessThan %bool %159 %uint_2
+        %158 = OpLogicalNot %bool %160
+               OpSelectionMerge %162 None
+               OpBranchConditional %158 %163 %162
+        %163 = OpLabel
+               OpBranch %155
+        %162 = OpLabel
+               OpStore %var_for_index %value_5
+        %167 = OpCompositeExtract %uint %dest_5 0
+        %169 = OpLoad %uint %i
+        %170 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %167 %uint_34 %169
+        %171 = OpLoad %uint %i
+        %173 = OpAccessChain %_ptr_Function_v3float %var_for_index %171
+        %174 = OpLoad %v3float %173
+               OpStore %170 %174
+               OpBranch %156
+        %156 = OpLabel
+        %175 = OpLoad %uint %i
+        %176 = OpIAdd %uint %175 %uint_1
+               OpStore %i %176
+               OpBranch %154
+        %155 = OpLabel
+               OpReturn
+               OpFunctionEnd
+ %main_inner = OpFunction %void None %177
+        %idx = OpFunctionParameter %uint
+        %180 = OpLabel
+        %182 = OpAccessChain %_ptr_StorageBuffer_float %sb %uint_0 %idx %uint_0
+               OpStore %182 %183
+        %185 = OpAccessChain %_ptr_StorageBuffer_int %sb %uint_0 %idx %uint_1
+               OpStore %185 %54
+        %187 = OpAccessChain %_ptr_StorageBuffer_uint %sb %uint_0 %idx %uint_2
+               OpStore %187 %59
+        %189 = OpAccessChain %_ptr_StorageBuffer_half %sb %uint_0 %idx %uint_3
+               OpStore %189 %190
+        %193 = OpAccessChain %_ptr_StorageBuffer_v2float %sb %uint_0 %idx %uint_4
+               OpStore %193 %194
+        %197 = OpAccessChain %_ptr_StorageBuffer_v2int %sb %uint_0 %idx %uint_5
+               OpStore %197 %198
+        %201 = OpAccessChain %_ptr_StorageBuffer_v2uint %sb %uint_0 %idx %uint_6
+               OpStore %201 %202
+        %205 = OpAccessChain %_ptr_StorageBuffer_v2half %sb %uint_0 %idx %uint_7
+               OpStore %205 %206
+        %208 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %idx %uint_8
+               OpStore %208 %209
+        %212 = OpAccessChain %_ptr_StorageBuffer_v3int %sb %uint_0 %idx %uint_9
+               OpStore %212 %213
+        %216 = OpAccessChain %_ptr_StorageBuffer_v3uint %sb %uint_0 %idx %uint_10
+               OpStore %216 %217
+        %219 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %idx %uint_11
+               OpStore %219 %220
+        %223 = OpAccessChain %_ptr_StorageBuffer_v4float %sb %uint_0 %idx %uint_12
+               OpStore %223 %224
+        %227 = OpAccessChain %_ptr_StorageBuffer_v4int %sb %uint_0 %idx %uint_13
+               OpStore %227 %228
+        %231 = OpAccessChain %_ptr_StorageBuffer_v4uint %sb %uint_0 %idx %uint_14
+               OpStore %231 %232
+        %235 = OpAccessChain %_ptr_StorageBuffer_v4half %sb %uint_0 %idx %uint_15
+               OpStore %235 %236
+        %239 = OpAccessChain %_ptr_StorageBuffer_mat2v2float %sb %uint_0 %idx %uint_16
+               OpStore %239 %240
+        %242 = OpCompositeConstruct %_arr_uint_uint_1 %idx
+        %241 = OpFunctionCall %void %assign_and_preserve_padding_sb_arr_X_mat2x3_f32 %242 %243
+        %246 = OpAccessChain %_ptr_StorageBuffer_mat2v4float %sb %uint_0 %idx %uint_18
+               OpStore %246 %247
+        %250 = OpAccessChain %_ptr_StorageBuffer_mat3v2float %sb %uint_0 %idx %uint_19
+               OpStore %250 %251
+        %252 = OpFunctionCall %void %assign_and_preserve_padding_1_sb_arr_X_mat3x3_f32 %242 %253
+        %256 = OpAccessChain %_ptr_StorageBuffer_mat3v4float %sb %uint_0 %idx %uint_21
+               OpStore %256 %257
+        %260 = OpAccessChain %_ptr_StorageBuffer_mat4v2float %sb %uint_0 %idx %uint_22
+               OpStore %260 %261
+        %262 = OpFunctionCall %void %assign_and_preserve_padding_2_sb_arr_X_mat4x3_f32 %242 %263
+        %266 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %sb %uint_0 %idx %uint_24
+               OpStore %266 %267
+        %270 = OpAccessChain %_ptr_StorageBuffer_mat2v2half %sb %uint_0 %idx %uint_25
+               OpStore %270 %271
+        %272 = OpFunctionCall %void %assign_and_preserve_padding_3_sb_arr_X_mat2x3_f16 %242 %273
+        %276 = OpAccessChain %_ptr_StorageBuffer_mat2v4half %sb %uint_0 %idx %uint_27
+               OpStore %276 %277
+        %280 = OpAccessChain %_ptr_StorageBuffer_mat3v2half %sb %uint_0 %idx %uint_28
+               OpStore %280 %281
+        %282 = OpFunctionCall %void %assign_and_preserve_padding_4_sb_arr_X_mat3x3_f16 %242 %283
+        %286 = OpAccessChain %_ptr_StorageBuffer_mat3v4half %sb %uint_0 %idx %uint_30
+               OpStore %286 %287
+        %290 = OpAccessChain %_ptr_StorageBuffer_mat4v2half %sb %uint_0 %idx %uint_31
+               OpStore %290 %291
+        %292 = OpFunctionCall %void %assign_and_preserve_padding_5_sb_arr_X_mat4x3_f16 %242 %293
+        %296 = OpAccessChain %_ptr_StorageBuffer_mat4v4half %sb %uint_0 %idx %uint_33
+               OpStore %296 %297
+        %298 = OpFunctionCall %void %assign_and_preserve_padding_6_sb_arr_X_arr2_vec3_f32 %242 %166
+        %301 = OpAccessChain %_ptr_StorageBuffer__arr_mat4v2half_uint_2 %sb %uint_0 %idx %uint_35
+               OpStore %301 %302
+               OpReturn
+               OpFunctionEnd
+       %main = OpFunction %void None %303
+        %305 = OpLabel
+        %307 = OpLoad %uint %idx_1
+        %306 = OpFunctionCall %void %main_inner %307
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/storage/static_index/write.wgsl.expected.glsl b/test/tint/buffer/storage/static_index/write.wgsl.expected.glsl
index e27e947..b52f19c 100644
--- a/test/tint/buffer/storage/static_index/write.wgsl.expected.glsl
+++ b/test/tint/buffer/storage/static_index/write.wgsl.expected.glsl
@@ -46,7 +46,25 @@
   S inner;
 } sb;
 
-void assign_and_preserve_padding_sb_arr2_vec3_f32(vec3 value[2]) {
+void assign_and_preserve_padding_sb_mat2x3_f32(mat2x3 value) {
+  sb.inner.mat2x3_f32[0] = value[0u];
+  sb.inner.mat2x3_f32[1] = value[1u];
+}
+
+void assign_and_preserve_padding_1_sb_mat3x3_f32(mat3 value) {
+  sb.inner.mat3x3_f32[0] = value[0u];
+  sb.inner.mat3x3_f32[1] = value[1u];
+  sb.inner.mat3x3_f32[2] = value[2u];
+}
+
+void assign_and_preserve_padding_2_sb_mat4x3_f32(mat4x3 value) {
+  sb.inner.mat4x3_f32[0] = value[0u];
+  sb.inner.mat4x3_f32[1] = value[1u];
+  sb.inner.mat4x3_f32[2] = value[2u];
+  sb.inner.mat4x3_f32[3] = value[3u];
+}
+
+void assign_and_preserve_padding_3_sb_arr2_vec3_f32(vec3 value[2]) {
   {
     for(uint i = 0u; (i < 2u); i = (i + 1u)) {
       sb.inner.arr2_vec3_f32[i] = value[i];
@@ -68,16 +86,16 @@
   sb.inner.vec4_i32 = ivec4(0);
   sb.inner.vec4_u32 = uvec4(0u);
   sb.inner.mat2x2_f32 = mat2(vec2(0.0f), vec2(0.0f));
-  sb.inner.mat2x3_f32 = mat2x3(vec3(0.0f), vec3(0.0f));
+  assign_and_preserve_padding_sb_mat2x3_f32(mat2x3(vec3(0.0f), vec3(0.0f)));
   sb.inner.mat2x4_f32 = mat2x4(vec4(0.0f), vec4(0.0f));
   sb.inner.mat3x2_f32 = mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f));
-  sb.inner.mat3x3_f32 = mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f));
+  assign_and_preserve_padding_1_sb_mat3x3_f32(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f)));
   sb.inner.mat3x4_f32 = mat3x4(vec4(0.0f), vec4(0.0f), vec4(0.0f));
   sb.inner.mat4x2_f32 = mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f));
-  sb.inner.mat4x3_f32 = mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f));
+  assign_and_preserve_padding_2_sb_mat4x3_f32(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f)));
   sb.inner.mat4x4_f32 = mat4(vec4(0.0f), vec4(0.0f), vec4(0.0f), vec4(0.0f));
   vec3 tint_symbol_1[2] = vec3[2](vec3(0.0f), vec3(0.0f));
-  assign_and_preserve_padding_sb_arr2_vec3_f32(tint_symbol_1);
+  assign_and_preserve_padding_3_sb_arr2_vec3_f32(tint_symbol_1);
   Inner tint_symbol_2 = Inner(0, 0.0f);
   sb.inner.struct_inner = tint_symbol_2;
   Inner tint_symbol_3[4] = Inner[4](Inner(0, 0.0f), Inner(0, 0.0f), Inner(0, 0.0f), Inner(0, 0.0f));
diff --git a/test/tint/buffer/storage/static_index/write.wgsl.expected.msl b/test/tint/buffer/storage/static_index/write.wgsl.expected.msl
index 3fda2a5..2c5bfa3 100644
--- a/test/tint/buffer/storage/static_index/write.wgsl.expected.msl
+++ b/test/tint/buffer/storage/static_index/write.wgsl.expected.msl
@@ -53,7 +53,25 @@
   /* 0x0248 */ tint_array<int8_t, 8> tint_pad_6;
 };
 
-void assign_and_preserve_padding(device tint_array<float3, 2>* const dest, tint_array<float3, 2> value) {
+void assign_and_preserve_padding(device float2x3* const dest, float2x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+}
+
+void assign_and_preserve_padding_1(device float3x3* const dest, float3x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+}
+
+void assign_and_preserve_padding_2(device float4x3* const dest, float4x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+  (*(dest))[3u] = value[3u];
+}
+
+void assign_and_preserve_padding_3(device tint_array<float3, 2>* const dest, tint_array<float3, 2> value) {
   for(uint i = 0u; (i < 2u); i = (i + 1u)) {
     (*(dest))[i] = value[i];
   }
@@ -73,16 +91,16 @@
   (*(tint_symbol_4)).vec4_i32 = int4(0);
   (*(tint_symbol_4)).vec4_u32 = uint4(0u);
   (*(tint_symbol_4)).mat2x2_f32 = float2x2(float2(0.0f), float2(0.0f));
-  (*(tint_symbol_4)).mat2x3_f32 = float2x3(float3(0.0f), float3(0.0f));
+  assign_and_preserve_padding(&((*(tint_symbol_4)).mat2x3_f32), float2x3(float3(0.0f), float3(0.0f)));
   (*(tint_symbol_4)).mat2x4_f32 = float2x4(float4(0.0f), float4(0.0f));
   (*(tint_symbol_4)).mat3x2_f32 = float3x2(float2(0.0f), float2(0.0f), float2(0.0f));
-  (*(tint_symbol_4)).mat3x3_f32 = float3x3(float3(0.0f), float3(0.0f), float3(0.0f));
+  assign_and_preserve_padding_1(&((*(tint_symbol_4)).mat3x3_f32), float3x3(float3(0.0f), float3(0.0f), float3(0.0f)));
   (*(tint_symbol_4)).mat3x4_f32 = float3x4(float4(0.0f), float4(0.0f), float4(0.0f));
   (*(tint_symbol_4)).mat4x2_f32 = float4x2(float2(0.0f), float2(0.0f), float2(0.0f), float2(0.0f));
-  (*(tint_symbol_4)).mat4x3_f32 = float4x3(float3(0.0f), float3(0.0f), float3(0.0f), float3(0.0f));
+  assign_and_preserve_padding_2(&((*(tint_symbol_4)).mat4x3_f32), float4x3(float3(0.0f), float3(0.0f), float3(0.0f), float3(0.0f)));
   (*(tint_symbol_4)).mat4x4_f32 = float4x4(float4(0.0f), float4(0.0f), float4(0.0f), float4(0.0f));
   tint_array<float3, 2> const tint_symbol_1 = tint_array<float3, 2>{};
-  assign_and_preserve_padding(&((*(tint_symbol_4)).arr2_vec3_f32), tint_symbol_1);
+  assign_and_preserve_padding_3(&((*(tint_symbol_4)).arr2_vec3_f32), tint_symbol_1);
   Inner const tint_symbol_2 = Inner{};
   (*(tint_symbol_4)).struct_inner = tint_symbol_2;
   tint_array<Inner, 4> const tint_symbol_3 = tint_array<Inner, 4>{};
diff --git a/test/tint/buffer/storage/static_index/write.wgsl.expected.spvasm b/test/tint/buffer/storage/static_index/write.wgsl.expected.spvasm
index 7987943..daebc55 100644
--- a/test/tint/buffer/storage/static_index/write.wgsl.expected.spvasm
+++ b/test/tint/buffer/storage/static_index/write.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 154
+; Bound: 184
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -38,8 +38,14 @@
                OpMemberName %Inner 1 "scalar_f32"
                OpMemberName %S 23 "array_struct_inner"
                OpName %sb "sb"
-               OpName %assign_and_preserve_padding_sb_arr2_vec3_f32 "assign_and_preserve_padding_sb_arr2_vec3_f32"
+               OpName %assign_and_preserve_padding_sb_mat2x3_f32 "assign_and_preserve_padding_sb_mat2x3_f32"
                OpName %value "value"
+               OpName %assign_and_preserve_padding_1_sb_mat3x3_f32 "assign_and_preserve_padding_1_sb_mat3x3_f32"
+               OpName %value_0 "value"
+               OpName %assign_and_preserve_padding_2_sb_mat4x3_f32 "assign_and_preserve_padding_2_sb_mat4x3_f32"
+               OpName %value_1 "value"
+               OpName %assign_and_preserve_padding_3_sb_arr2_vec3_f32 "assign_and_preserve_padding_3_sb_arr2_vec3_f32"
+               OpName %value_2 "value"
                OpName %i "i"
                OpName %var_for_index "var_for_index"
                OpName %main "main"
@@ -124,164 +130,206 @@
 %_ptr_StorageBuffer_sb_block = OpTypePointer StorageBuffer %sb_block
          %sb = OpVariable %_ptr_StorageBuffer_sb_block StorageBuffer
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void %_arr_v3float_uint_2
-         %36 = OpConstantNull %uint
+         %31 = OpTypeFunction %void %mat2v3float
+     %uint_0 = OpConstant %uint 0
+    %uint_13 = OpConstant %uint 13
+         %38 = OpConstantNull %int
+%_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
+         %41 = OpConstantNull %uint
+      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
+         %47 = OpTypeFunction %void %mat3v3float
+    %uint_16 = OpConstant %uint 16
+      %int_2 = OpConstant %int 2
+         %59 = OpTypeFunction %void %mat4v3float
+    %uint_19 = OpConstant %uint 19
+      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
+         %74 = OpTypeFunction %void %_arr_v3float_uint_2
 %_ptr_Function_uint = OpTypePointer Function %uint
        %bool = OpTypeBool
 %_ptr_Function__arr_v3float_uint_2 = OpTypePointer Function %_arr_v3float_uint_2
-         %51 = OpConstantNull %_arr_v3float_uint_2
-     %uint_0 = OpConstant %uint 0
+         %92 = OpConstantNull %_arr_v3float_uint_2
     %uint_21 = OpConstant %uint 21
-%_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
 %_ptr_Function_v3float = OpTypePointer Function %v3float
-     %uint_1 = OpConstant %uint 1
-         %64 = OpTypeFunction %void
+        %102 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-         %69 = OpConstantNull %float
+        %107 = OpConstantNull %float
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-         %72 = OpConstantNull %int
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-     %uint_3 = OpConstant %uint 3
 %_ptr_StorageBuffer_v2float = OpTypePointer StorageBuffer %v2float
-         %78 = OpConstantNull %v2float
+        %114 = OpConstantNull %v2float
 %_ptr_StorageBuffer_v2int = OpTypePointer StorageBuffer %v2int
-         %81 = OpConstantNull %v2int
+        %117 = OpConstantNull %v2int
      %uint_5 = OpConstant %uint 5
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
-         %85 = OpConstantNull %v2uint
+        %121 = OpConstantNull %v2uint
      %uint_6 = OpConstant %uint 6
-         %88 = OpConstantNull %v3float
+        %124 = OpConstantNull %v3float
      %uint_7 = OpConstant %uint 7
 %_ptr_StorageBuffer_v3int = OpTypePointer StorageBuffer %v3int
-         %92 = OpConstantNull %v3int
+        %128 = OpConstantNull %v3int
      %uint_8 = OpConstant %uint 8
 %_ptr_StorageBuffer_v3uint = OpTypePointer StorageBuffer %v3uint
-         %96 = OpConstantNull %v3uint
+        %132 = OpConstantNull %v3uint
      %uint_9 = OpConstant %uint 9
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-        %100 = OpConstantNull %v4float
+        %136 = OpConstantNull %v4float
     %uint_10 = OpConstant %uint 10
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-        %104 = OpConstantNull %v4int
+        %140 = OpConstantNull %v4int
     %uint_11 = OpConstant %uint 11
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
-        %108 = OpConstantNull %v4uint
+        %144 = OpConstantNull %v4uint
     %uint_12 = OpConstant %uint 12
 %_ptr_StorageBuffer_mat2v2float = OpTypePointer StorageBuffer %mat2v2float
-        %112 = OpConstantNull %mat2v2float
-    %uint_13 = OpConstant %uint 13
-%_ptr_StorageBuffer_mat2v3float = OpTypePointer StorageBuffer %mat2v3float
-        %116 = OpConstantNull %mat2v3float
+        %148 = OpConstantNull %mat2v2float
+        %150 = OpConstantNull %mat2v3float
     %uint_14 = OpConstant %uint 14
 %_ptr_StorageBuffer_mat2v4float = OpTypePointer StorageBuffer %mat2v4float
-        %120 = OpConstantNull %mat2v4float
+        %154 = OpConstantNull %mat2v4float
     %uint_15 = OpConstant %uint 15
 %_ptr_StorageBuffer_mat3v2float = OpTypePointer StorageBuffer %mat3v2float
-        %124 = OpConstantNull %mat3v2float
-    %uint_16 = OpConstant %uint 16
-%_ptr_StorageBuffer_mat3v3float = OpTypePointer StorageBuffer %mat3v3float
-        %128 = OpConstantNull %mat3v3float
+        %158 = OpConstantNull %mat3v2float
+        %160 = OpConstantNull %mat3v3float
     %uint_17 = OpConstant %uint 17
 %_ptr_StorageBuffer_mat3v4float = OpTypePointer StorageBuffer %mat3v4float
-        %132 = OpConstantNull %mat3v4float
+        %164 = OpConstantNull %mat3v4float
     %uint_18 = OpConstant %uint 18
 %_ptr_StorageBuffer_mat4v2float = OpTypePointer StorageBuffer %mat4v2float
-        %136 = OpConstantNull %mat4v2float
-    %uint_19 = OpConstant %uint 19
-%_ptr_StorageBuffer_mat4v3float = OpTypePointer StorageBuffer %mat4v3float
-        %140 = OpConstantNull %mat4v3float
+        %168 = OpConstantNull %mat4v2float
+        %170 = OpConstantNull %mat4v3float
     %uint_20 = OpConstant %uint 20
 %_ptr_StorageBuffer_mat4v4float = OpTypePointer StorageBuffer %mat4v4float
-        %144 = OpConstantNull %mat4v4float
+        %174 = OpConstantNull %mat4v4float
     %uint_22 = OpConstant %uint 22
 %_ptr_StorageBuffer_Inner = OpTypePointer StorageBuffer %Inner
-        %149 = OpConstantNull %Inner
+        %179 = OpConstantNull %Inner
     %uint_23 = OpConstant %uint 23
 %_ptr_StorageBuffer__arr_Inner_uint_4 = OpTypePointer StorageBuffer %_arr_Inner_uint_4
-        %153 = OpConstantNull %_arr_Inner_uint_4
-%assign_and_preserve_padding_sb_arr2_vec3_f32 = OpFunction %void None %31
-      %value = OpFunctionParameter %_arr_v3float_uint_2
+        %183 = OpConstantNull %_arr_Inner_uint_4
+%assign_and_preserve_padding_sb_mat2x3_f32 = OpFunction %void None %31
+      %value = OpFunctionParameter %mat2v3float
          %35 = OpLabel
-          %i = OpVariable %_ptr_Function_uint Function %36
-%var_for_index = OpVariable %_ptr_Function__arr_v3float_uint_2 Function %51
-               OpStore %i %36
-               OpBranch %39
-         %39 = OpLabel
-               OpLoopMerge %40 %41 None
-               OpBranch %42
-         %42 = OpLabel
-         %44 = OpLoad %uint %i
-         %45 = OpULessThan %bool %44 %uint_2
-         %43 = OpLogicalNot %bool %45
-               OpSelectionMerge %47 None
-               OpBranchConditional %43 %48 %47
-         %48 = OpLabel
-               OpBranch %40
-         %47 = OpLabel
-               OpStore %var_for_index %value
-         %54 = OpLoad %uint %i
-         %56 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %uint_21 %54
-         %57 = OpLoad %uint %i
-         %59 = OpAccessChain %_ptr_Function_v3float %var_for_index %57
-         %60 = OpLoad %v3float %59
-               OpStore %56 %60
-               OpBranch %41
-         %41 = OpLabel
-         %61 = OpLoad %uint %i
-         %63 = OpIAdd %uint %61 %uint_1
-               OpStore %i %63
-               OpBranch %39
-         %40 = OpLabel
+         %40 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %uint_13 %38
+         %42 = OpCompositeExtract %v3float %value 0
+               OpStore %40 %42
+         %44 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %uint_13 %int_1
+         %46 = OpCompositeExtract %v3float %value 1
+               OpStore %44 %46
                OpReturn
                OpFunctionEnd
-       %main = OpFunction %void None %64
-         %66 = OpLabel
-         %68 = OpAccessChain %_ptr_StorageBuffer_float %sb %uint_0 %uint_0
+%assign_and_preserve_padding_1_sb_mat3x3_f32 = OpFunction %void None %47
+    %value_0 = OpFunctionParameter %mat3v3float
+         %50 = OpLabel
+         %52 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %uint_16 %38
+         %53 = OpCompositeExtract %v3float %value_0 0
+               OpStore %52 %53
+         %54 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %uint_16 %int_1
+         %55 = OpCompositeExtract %v3float %value_0 1
+               OpStore %54 %55
+         %57 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %uint_16 %int_2
+         %58 = OpCompositeExtract %v3float %value_0 2
+               OpStore %57 %58
+               OpReturn
+               OpFunctionEnd
+%assign_and_preserve_padding_2_sb_mat4x3_f32 = OpFunction %void None %59
+    %value_1 = OpFunctionParameter %mat4v3float
+         %62 = OpLabel
+         %64 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %uint_19 %38
+         %65 = OpCompositeExtract %v3float %value_1 0
+               OpStore %64 %65
+         %66 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %uint_19 %int_1
+         %67 = OpCompositeExtract %v3float %value_1 1
+               OpStore %66 %67
+         %68 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %uint_19 %int_2
+         %69 = OpCompositeExtract %v3float %value_1 2
                OpStore %68 %69
-         %71 = OpAccessChain %_ptr_StorageBuffer_int %sb %uint_0 %uint_1
-               OpStore %71 %72
-         %74 = OpAccessChain %_ptr_StorageBuffer_uint %sb %uint_0 %uint_2
-               OpStore %74 %36
-         %77 = OpAccessChain %_ptr_StorageBuffer_v2float %sb %uint_0 %uint_3
-               OpStore %77 %78
-         %80 = OpAccessChain %_ptr_StorageBuffer_v2int %sb %uint_0 %uint_4
-               OpStore %80 %81
-         %84 = OpAccessChain %_ptr_StorageBuffer_v2uint %sb %uint_0 %uint_5
-               OpStore %84 %85
-         %87 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %uint_6
-               OpStore %87 %88
-         %91 = OpAccessChain %_ptr_StorageBuffer_v3int %sb %uint_0 %uint_7
-               OpStore %91 %92
-         %95 = OpAccessChain %_ptr_StorageBuffer_v3uint %sb %uint_0 %uint_8
-               OpStore %95 %96
-         %99 = OpAccessChain %_ptr_StorageBuffer_v4float %sb %uint_0 %uint_9
-               OpStore %99 %100
-        %103 = OpAccessChain %_ptr_StorageBuffer_v4int %sb %uint_0 %uint_10
-               OpStore %103 %104
-        %107 = OpAccessChain %_ptr_StorageBuffer_v4uint %sb %uint_0 %uint_11
-               OpStore %107 %108
-        %111 = OpAccessChain %_ptr_StorageBuffer_mat2v2float %sb %uint_0 %uint_12
-               OpStore %111 %112
-        %115 = OpAccessChain %_ptr_StorageBuffer_mat2v3float %sb %uint_0 %uint_13
-               OpStore %115 %116
-        %119 = OpAccessChain %_ptr_StorageBuffer_mat2v4float %sb %uint_0 %uint_14
-               OpStore %119 %120
-        %123 = OpAccessChain %_ptr_StorageBuffer_mat3v2float %sb %uint_0 %uint_15
+         %71 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %uint_19 %int_3
+         %73 = OpCompositeExtract %v3float %value_1 3
+               OpStore %71 %73
+               OpReturn
+               OpFunctionEnd
+%assign_and_preserve_padding_3_sb_arr2_vec3_f32 = OpFunction %void None %74
+    %value_2 = OpFunctionParameter %_arr_v3float_uint_2
+         %77 = OpLabel
+          %i = OpVariable %_ptr_Function_uint Function %41
+%var_for_index = OpVariable %_ptr_Function__arr_v3float_uint_2 Function %92
+               OpStore %i %41
+               OpBranch %80
+         %80 = OpLabel
+               OpLoopMerge %81 %82 None
+               OpBranch %83
+         %83 = OpLabel
+         %85 = OpLoad %uint %i
+         %86 = OpULessThan %bool %85 %uint_2
+         %84 = OpLogicalNot %bool %86
+               OpSelectionMerge %88 None
+               OpBranchConditional %84 %89 %88
+         %89 = OpLabel
+               OpBranch %81
+         %88 = OpLabel
+               OpStore %var_for_index %value_2
+         %94 = OpLoad %uint %i
+         %95 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %uint_21 %94
+         %96 = OpLoad %uint %i
+         %98 = OpAccessChain %_ptr_Function_v3float %var_for_index %96
+         %99 = OpLoad %v3float %98
+               OpStore %95 %99
+               OpBranch %82
+         %82 = OpLabel
+        %100 = OpLoad %uint %i
+        %101 = OpIAdd %uint %100 %uint_1
+               OpStore %i %101
+               OpBranch %80
+         %81 = OpLabel
+               OpReturn
+               OpFunctionEnd
+       %main = OpFunction %void None %102
+        %104 = OpLabel
+        %106 = OpAccessChain %_ptr_StorageBuffer_float %sb %uint_0 %uint_0
+               OpStore %106 %107
+        %109 = OpAccessChain %_ptr_StorageBuffer_int %sb %uint_0 %uint_1
+               OpStore %109 %38
+        %111 = OpAccessChain %_ptr_StorageBuffer_uint %sb %uint_0 %uint_2
+               OpStore %111 %41
+        %113 = OpAccessChain %_ptr_StorageBuffer_v2float %sb %uint_0 %uint_3
+               OpStore %113 %114
+        %116 = OpAccessChain %_ptr_StorageBuffer_v2int %sb %uint_0 %uint_4
+               OpStore %116 %117
+        %120 = OpAccessChain %_ptr_StorageBuffer_v2uint %sb %uint_0 %uint_5
+               OpStore %120 %121
+        %123 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %uint_6
                OpStore %123 %124
-        %127 = OpAccessChain %_ptr_StorageBuffer_mat3v3float %sb %uint_0 %uint_16
+        %127 = OpAccessChain %_ptr_StorageBuffer_v3int %sb %uint_0 %uint_7
                OpStore %127 %128
-        %131 = OpAccessChain %_ptr_StorageBuffer_mat3v4float %sb %uint_0 %uint_17
+        %131 = OpAccessChain %_ptr_StorageBuffer_v3uint %sb %uint_0 %uint_8
                OpStore %131 %132
-        %135 = OpAccessChain %_ptr_StorageBuffer_mat4v2float %sb %uint_0 %uint_18
+        %135 = OpAccessChain %_ptr_StorageBuffer_v4float %sb %uint_0 %uint_9
                OpStore %135 %136
-        %139 = OpAccessChain %_ptr_StorageBuffer_mat4v3float %sb %uint_0 %uint_19
+        %139 = OpAccessChain %_ptr_StorageBuffer_v4int %sb %uint_0 %uint_10
                OpStore %139 %140
-        %143 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %sb %uint_0 %uint_20
+        %143 = OpAccessChain %_ptr_StorageBuffer_v4uint %sb %uint_0 %uint_11
                OpStore %143 %144
-        %145 = OpFunctionCall %void %assign_and_preserve_padding_sb_arr2_vec3_f32 %51
-        %148 = OpAccessChain %_ptr_StorageBuffer_Inner %sb %uint_0 %uint_22
-               OpStore %148 %149
-        %152 = OpAccessChain %_ptr_StorageBuffer__arr_Inner_uint_4 %sb %uint_0 %uint_23
-               OpStore %152 %153
+        %147 = OpAccessChain %_ptr_StorageBuffer_mat2v2float %sb %uint_0 %uint_12
+               OpStore %147 %148
+        %149 = OpFunctionCall %void %assign_and_preserve_padding_sb_mat2x3_f32 %150
+        %153 = OpAccessChain %_ptr_StorageBuffer_mat2v4float %sb %uint_0 %uint_14
+               OpStore %153 %154
+        %157 = OpAccessChain %_ptr_StorageBuffer_mat3v2float %sb %uint_0 %uint_15
+               OpStore %157 %158
+        %159 = OpFunctionCall %void %assign_and_preserve_padding_1_sb_mat3x3_f32 %160
+        %163 = OpAccessChain %_ptr_StorageBuffer_mat3v4float %sb %uint_0 %uint_17
+               OpStore %163 %164
+        %167 = OpAccessChain %_ptr_StorageBuffer_mat4v2float %sb %uint_0 %uint_18
+               OpStore %167 %168
+        %169 = OpFunctionCall %void %assign_and_preserve_padding_2_sb_mat4x3_f32 %170
+        %173 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %sb %uint_0 %uint_20
+               OpStore %173 %174
+        %175 = OpFunctionCall %void %assign_and_preserve_padding_3_sb_arr2_vec3_f32 %92
+        %178 = OpAccessChain %_ptr_StorageBuffer_Inner %sb %uint_0 %uint_22
+               OpStore %178 %179
+        %182 = OpAccessChain %_ptr_StorageBuffer__arr_Inner_uint_4 %sb %uint_0 %uint_23
+               OpStore %182 %183
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/storage/static_index/write_f16.wgsl.expected.glsl b/test/tint/buffer/storage/static_index/write_f16.wgsl.expected.glsl
index 30cc24f..34c75e1 100644
--- a/test/tint/buffer/storage/static_index/write_f16.wgsl.expected.glsl
+++ b/test/tint/buffer/storage/static_index/write_f16.wgsl.expected.glsl
@@ -66,7 +66,43 @@
   S inner;
 } sb;
 
-void assign_and_preserve_padding_sb_arr2_vec3_f32(vec3 value[2]) {
+void assign_and_preserve_padding_sb_mat2x3_f32(mat2x3 value) {
+  sb.inner.mat2x3_f32[0] = value[0u];
+  sb.inner.mat2x3_f32[1] = value[1u];
+}
+
+void assign_and_preserve_padding_1_sb_mat3x3_f32(mat3 value) {
+  sb.inner.mat3x3_f32[0] = value[0u];
+  sb.inner.mat3x3_f32[1] = value[1u];
+  sb.inner.mat3x3_f32[2] = value[2u];
+}
+
+void assign_and_preserve_padding_2_sb_mat4x3_f32(mat4x3 value) {
+  sb.inner.mat4x3_f32[0] = value[0u];
+  sb.inner.mat4x3_f32[1] = value[1u];
+  sb.inner.mat4x3_f32[2] = value[2u];
+  sb.inner.mat4x3_f32[3] = value[3u];
+}
+
+void assign_and_preserve_padding_3_sb_mat2x3_f16(f16mat2x3 value) {
+  sb.inner.mat2x3_f16[0] = value[0u];
+  sb.inner.mat2x3_f16[1] = value[1u];
+}
+
+void assign_and_preserve_padding_4_sb_mat3x3_f16(f16mat3 value) {
+  sb.inner.mat3x3_f16[0] = value[0u];
+  sb.inner.mat3x3_f16[1] = value[1u];
+  sb.inner.mat3x3_f16[2] = value[2u];
+}
+
+void assign_and_preserve_padding_5_sb_mat4x3_f16(f16mat4x3 value) {
+  sb.inner.mat4x3_f16[0] = value[0u];
+  sb.inner.mat4x3_f16[1] = value[1u];
+  sb.inner.mat4x3_f16[2] = value[2u];
+  sb.inner.mat4x3_f16[3] = value[3u];
+}
+
+void assign_and_preserve_padding_6_sb_arr2_vec3_f32(vec3 value[2]) {
   {
     for(uint i = 0u; (i < 2u); i = (i + 1u)) {
       sb.inner.arr2_vec3_f32[i] = value[i];
@@ -74,23 +110,23 @@
   }
 }
 
-void assign_and_preserve_padding_1_sb_struct_inner(Inner value) {
+void assign_and_preserve_padding_7_sb_struct_inner(Inner value) {
   sb.inner.struct_inner.scalar_i32 = value.scalar_i32;
   sb.inner.struct_inner.scalar_f32 = value.scalar_f32;
   sb.inner.struct_inner.scalar_f16 = value.scalar_f16;
 }
 
-void assign_and_preserve_padding_1_sb_array_struct_inner_X(uint dest[1], Inner value) {
+void assign_and_preserve_padding_7_sb_array_struct_inner_X(uint dest[1], Inner value) {
   sb.inner.array_struct_inner[dest[0]].scalar_i32 = value.scalar_i32;
   sb.inner.array_struct_inner[dest[0]].scalar_f32 = value.scalar_f32;
   sb.inner.array_struct_inner[dest[0]].scalar_f16 = value.scalar_f16;
 }
 
-void assign_and_preserve_padding_2_sb_array_struct_inner(Inner value[4]) {
+void assign_and_preserve_padding_8_sb_array_struct_inner(Inner value[4]) {
   {
     for(uint i = 0u; (i < 4u); i = (i + 1u)) {
       uint tint_symbol_1[1] = uint[1](i);
-      assign_and_preserve_padding_1_sb_array_struct_inner_X(tint_symbol_1, value[i]);
+      assign_and_preserve_padding_7_sb_array_struct_inner_X(tint_symbol_1, value[i]);
     }
   }
 }
@@ -113,31 +149,31 @@
   sb.inner.vec4_u32 = uvec4(0u);
   sb.inner.vec4_f16 = f16vec4(0.0hf);
   sb.inner.mat2x2_f32 = mat2(vec2(0.0f), vec2(0.0f));
-  sb.inner.mat2x3_f32 = mat2x3(vec3(0.0f), vec3(0.0f));
+  assign_and_preserve_padding_sb_mat2x3_f32(mat2x3(vec3(0.0f), vec3(0.0f)));
   sb.inner.mat2x4_f32 = mat2x4(vec4(0.0f), vec4(0.0f));
   sb.inner.mat3x2_f32 = mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f));
-  sb.inner.mat3x3_f32 = mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f));
+  assign_and_preserve_padding_1_sb_mat3x3_f32(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f)));
   sb.inner.mat3x4_f32 = mat3x4(vec4(0.0f), vec4(0.0f), vec4(0.0f));
   sb.inner.mat4x2_f32 = mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f));
-  sb.inner.mat4x3_f32 = mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f));
+  assign_and_preserve_padding_2_sb_mat4x3_f32(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f)));
   sb.inner.mat4x4_f32 = mat4(vec4(0.0f), vec4(0.0f), vec4(0.0f), vec4(0.0f));
   sb.inner.mat2x2_f16 = f16mat2(f16vec2(0.0hf), f16vec2(0.0hf));
-  sb.inner.mat2x3_f16 = f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf));
+  assign_and_preserve_padding_3_sb_mat2x3_f16(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf)));
   sb.inner.mat2x4_f16 = f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf));
   sb.inner.mat3x2_f16 = f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf));
-  sb.inner.mat3x3_f16 = f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf));
+  assign_and_preserve_padding_4_sb_mat3x3_f16(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf)));
   sb.inner.mat3x4_f16 = f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf));
   sb.inner.mat4x2_f16 = f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf));
-  sb.inner.mat4x3_f16 = f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf));
+  assign_and_preserve_padding_5_sb_mat4x3_f16(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf)));
   sb.inner.mat4x4_f16 = f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf));
   vec3 tint_symbol_2[2] = vec3[2](vec3(0.0f), vec3(0.0f));
-  assign_and_preserve_padding_sb_arr2_vec3_f32(tint_symbol_2);
+  assign_and_preserve_padding_6_sb_arr2_vec3_f32(tint_symbol_2);
   f16mat4x2 tint_symbol_3[2] = f16mat4x2[2](f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf)), f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf)));
   sb.inner.arr2_mat4x2_f16 = tint_symbol_3;
   Inner tint_symbol_4 = Inner(0, 0.0f, 0.0hf);
-  assign_and_preserve_padding_1_sb_struct_inner(tint_symbol_4);
+  assign_and_preserve_padding_7_sb_struct_inner(tint_symbol_4);
   Inner tint_symbol_5[4] = Inner[4](Inner(0, 0.0f, 0.0hf), Inner(0, 0.0f, 0.0hf), Inner(0, 0.0f, 0.0hf), Inner(0, 0.0f, 0.0hf));
-  assign_and_preserve_padding_2_sb_array_struct_inner(tint_symbol_5);
+  assign_and_preserve_padding_8_sb_array_struct_inner(tint_symbol_5);
 }
 
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/buffer/storage/static_index/write_f16.wgsl.expected.msl b/test/tint/buffer/storage/static_index/write_f16.wgsl.expected.msl
index df7a7b8..d9da3dd 100644
--- a/test/tint/buffer/storage/static_index/write_f16.wgsl.expected.msl
+++ b/test/tint/buffer/storage/static_index/write_f16.wgsl.expected.msl
@@ -73,21 +73,57 @@
   /* 0x035c */ tint_array<int8_t, 4> tint_pad_11;
 };
 
-void assign_and_preserve_padding(device tint_array<float3, 2>* const dest, tint_array<float3, 2> value) {
+void assign_and_preserve_padding(device float2x3* const dest, float2x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+}
+
+void assign_and_preserve_padding_1(device float3x3* const dest, float3x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+}
+
+void assign_and_preserve_padding_2(device float4x3* const dest, float4x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+  (*(dest))[3u] = value[3u];
+}
+
+void assign_and_preserve_padding_3(device half2x3* const dest, half2x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+}
+
+void assign_and_preserve_padding_4(device half3x3* const dest, half3x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+}
+
+void assign_and_preserve_padding_5(device half4x3* const dest, half4x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+  (*(dest))[3u] = value[3u];
+}
+
+void assign_and_preserve_padding_6(device tint_array<float3, 2>* const dest, tint_array<float3, 2> value) {
   for(uint i = 0u; (i < 2u); i = (i + 1u)) {
     (*(dest))[i] = value[i];
   }
 }
 
-void assign_and_preserve_padding_1(device Inner* const dest, Inner value) {
+void assign_and_preserve_padding_7(device Inner* const dest, Inner value) {
   (*(dest)).scalar_i32 = value.scalar_i32;
   (*(dest)).scalar_f32 = value.scalar_f32;
   (*(dest)).scalar_f16 = value.scalar_f16;
 }
 
-void assign_and_preserve_padding_2(device tint_array<Inner, 4>* const dest, tint_array<Inner, 4> value) {
+void assign_and_preserve_padding_8(device tint_array<Inner, 4>* const dest, tint_array<Inner, 4> value) {
   for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+    assign_and_preserve_padding_7(&((*(dest))[i]), value[i]);
   }
 }
 
@@ -109,31 +145,31 @@
   (*(tint_symbol_5)).vec4_u32 = uint4(0u);
   (*(tint_symbol_5)).vec4_f16 = half4(0.0h);
   (*(tint_symbol_5)).mat2x2_f32 = float2x2(float2(0.0f), float2(0.0f));
-  (*(tint_symbol_5)).mat2x3_f32 = float2x3(float3(0.0f), float3(0.0f));
+  assign_and_preserve_padding(&((*(tint_symbol_5)).mat2x3_f32), float2x3(float3(0.0f), float3(0.0f)));
   (*(tint_symbol_5)).mat2x4_f32 = float2x4(float4(0.0f), float4(0.0f));
   (*(tint_symbol_5)).mat3x2_f32 = float3x2(float2(0.0f), float2(0.0f), float2(0.0f));
-  (*(tint_symbol_5)).mat3x3_f32 = float3x3(float3(0.0f), float3(0.0f), float3(0.0f));
+  assign_and_preserve_padding_1(&((*(tint_symbol_5)).mat3x3_f32), float3x3(float3(0.0f), float3(0.0f), float3(0.0f)));
   (*(tint_symbol_5)).mat3x4_f32 = float3x4(float4(0.0f), float4(0.0f), float4(0.0f));
   (*(tint_symbol_5)).mat4x2_f32 = float4x2(float2(0.0f), float2(0.0f), float2(0.0f), float2(0.0f));
-  (*(tint_symbol_5)).mat4x3_f32 = float4x3(float3(0.0f), float3(0.0f), float3(0.0f), float3(0.0f));
+  assign_and_preserve_padding_2(&((*(tint_symbol_5)).mat4x3_f32), float4x3(float3(0.0f), float3(0.0f), float3(0.0f), float3(0.0f)));
   (*(tint_symbol_5)).mat4x4_f32 = float4x4(float4(0.0f), float4(0.0f), float4(0.0f), float4(0.0f));
   (*(tint_symbol_5)).mat2x2_f16 = half2x2(half2(0.0h), half2(0.0h));
-  (*(tint_symbol_5)).mat2x3_f16 = half2x3(half3(0.0h), half3(0.0h));
+  assign_and_preserve_padding_3(&((*(tint_symbol_5)).mat2x3_f16), half2x3(half3(0.0h), half3(0.0h)));
   (*(tint_symbol_5)).mat2x4_f16 = half2x4(half4(0.0h), half4(0.0h));
   (*(tint_symbol_5)).mat3x2_f16 = half3x2(half2(0.0h), half2(0.0h), half2(0.0h));
-  (*(tint_symbol_5)).mat3x3_f16 = half3x3(half3(0.0h), half3(0.0h), half3(0.0h));
+  assign_and_preserve_padding_4(&((*(tint_symbol_5)).mat3x3_f16), half3x3(half3(0.0h), half3(0.0h), half3(0.0h)));
   (*(tint_symbol_5)).mat3x4_f16 = half3x4(half4(0.0h), half4(0.0h), half4(0.0h));
   (*(tint_symbol_5)).mat4x2_f16 = half4x2(half2(0.0h), half2(0.0h), half2(0.0h), half2(0.0h));
-  (*(tint_symbol_5)).mat4x3_f16 = half4x3(half3(0.0h), half3(0.0h), half3(0.0h), half3(0.0h));
+  assign_and_preserve_padding_5(&((*(tint_symbol_5)).mat4x3_f16), half4x3(half3(0.0h), half3(0.0h), half3(0.0h), half3(0.0h)));
   (*(tint_symbol_5)).mat4x4_f16 = half4x4(half4(0.0h), half4(0.0h), half4(0.0h), half4(0.0h));
   tint_array<float3, 2> const tint_symbol_1 = tint_array<float3, 2>{};
-  assign_and_preserve_padding(&((*(tint_symbol_5)).arr2_vec3_f32), tint_symbol_1);
+  assign_and_preserve_padding_6(&((*(tint_symbol_5)).arr2_vec3_f32), tint_symbol_1);
   tint_array<half4x2, 2> const tint_symbol_4 = tint_array<half4x2, 2>{};
   (*(tint_symbol_5)).arr2_mat4x2_f16 = tint_symbol_4;
   Inner const tint_symbol_2 = Inner{};
-  assign_and_preserve_padding_1(&((*(tint_symbol_5)).struct_inner), tint_symbol_2);
+  assign_and_preserve_padding_7(&((*(tint_symbol_5)).struct_inner), tint_symbol_2);
   tint_array<Inner, 4> const tint_symbol_3 = tint_array<Inner, 4>{};
-  assign_and_preserve_padding_2(&((*(tint_symbol_5)).array_struct_inner), tint_symbol_3);
+  assign_and_preserve_padding_8(&((*(tint_symbol_5)).array_struct_inner), tint_symbol_3);
   return;
 }
 
diff --git a/test/tint/buffer/storage/static_index/write_f16.wgsl.expected.spvasm b/test/tint/buffer/storage/static_index/write_f16.wgsl.expected.spvasm
index d998b28..b6fc7ef 100644
--- a/test/tint/buffer/storage/static_index/write_f16.wgsl.expected.spvasm
+++ b/test/tint/buffer/storage/static_index/write_f16.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 272
+; Bound: 329
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -57,17 +57,29 @@
                OpMemberName %Inner 2 "scalar_f16"
                OpMemberName %S 37 "array_struct_inner"
                OpName %sb "sb"
-               OpName %assign_and_preserve_padding_sb_arr2_vec3_f32 "assign_and_preserve_padding_sb_arr2_vec3_f32"
+               OpName %assign_and_preserve_padding_sb_mat2x3_f32 "assign_and_preserve_padding_sb_mat2x3_f32"
                OpName %value "value"
+               OpName %assign_and_preserve_padding_1_sb_mat3x3_f32 "assign_and_preserve_padding_1_sb_mat3x3_f32"
+               OpName %value_0 "value"
+               OpName %assign_and_preserve_padding_2_sb_mat4x3_f32 "assign_and_preserve_padding_2_sb_mat4x3_f32"
+               OpName %value_1 "value"
+               OpName %assign_and_preserve_padding_3_sb_mat2x3_f16 "assign_and_preserve_padding_3_sb_mat2x3_f16"
+               OpName %value_2 "value"
+               OpName %assign_and_preserve_padding_4_sb_mat3x3_f16 "assign_and_preserve_padding_4_sb_mat3x3_f16"
+               OpName %value_3 "value"
+               OpName %assign_and_preserve_padding_5_sb_mat4x3_f16 "assign_and_preserve_padding_5_sb_mat4x3_f16"
+               OpName %value_4 "value"
+               OpName %assign_and_preserve_padding_6_sb_arr2_vec3_f32 "assign_and_preserve_padding_6_sb_arr2_vec3_f32"
+               OpName %value_5 "value"
                OpName %i "i"
                OpName %var_for_index "var_for_index"
-               OpName %assign_and_preserve_padding_1_sb_struct_inner "assign_and_preserve_padding_1_sb_struct_inner"
-               OpName %value_0 "value"
-               OpName %assign_and_preserve_padding_1_sb_array_struct_inner_X "assign_and_preserve_padding_1_sb_array_struct_inner_X"
+               OpName %assign_and_preserve_padding_7_sb_struct_inner "assign_and_preserve_padding_7_sb_struct_inner"
+               OpName %value_6 "value"
+               OpName %assign_and_preserve_padding_7_sb_array_struct_inner_X "assign_and_preserve_padding_7_sb_array_struct_inner_X"
                OpName %dest "dest"
-               OpName %value_1 "value"
-               OpName %assign_and_preserve_padding_2_sb_array_struct_inner "assign_and_preserve_padding_2_sb_array_struct_inner"
-               OpName %value_2 "value"
+               OpName %value_7 "value"
+               OpName %assign_and_preserve_padding_8_sb_array_struct_inner "assign_and_preserve_padding_8_sb_array_struct_inner"
+               OpName %value_8 "value"
                OpName %i_0 "i"
                OpName %var_for_index_1 "var_for_index_1"
                OpName %main "main"
@@ -203,303 +215,384 @@
 %_ptr_StorageBuffer_sb_block = OpTypePointer StorageBuffer %sb_block
          %sb = OpVariable %_ptr_StorageBuffer_sb_block StorageBuffer
        %void = OpTypeVoid
-         %45 = OpTypeFunction %void %_arr_v3float_uint_2
-         %50 = OpConstantNull %uint
+         %45 = OpTypeFunction %void %mat2v3float
+     %uint_0 = OpConstant %uint 0
+    %uint_17 = OpConstant %uint 17
+         %52 = OpConstantNull %int
+%_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
+         %55 = OpConstantNull %uint
+      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
+         %61 = OpTypeFunction %void %mat3v3float
+    %uint_20 = OpConstant %uint 20
+      %int_2 = OpConstant %int 2
+         %73 = OpTypeFunction %void %mat4v3float
+    %uint_23 = OpConstant %uint 23
+      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
+         %88 = OpTypeFunction %void %mat2v3half
+    %uint_26 = OpConstant %uint 26
+%_ptr_StorageBuffer_v3half = OpTypePointer StorageBuffer %v3half
+         %98 = OpTypeFunction %void %mat3v3half
+    %uint_29 = OpConstant %uint 29
+        %109 = OpTypeFunction %void %mat4v3half
+    %uint_32 = OpConstant %uint 32
+        %122 = OpTypeFunction %void %_arr_v3float_uint_2
 %_ptr_Function_uint = OpTypePointer Function %uint
        %bool = OpTypeBool
 %_ptr_Function__arr_v3float_uint_2 = OpTypePointer Function %_arr_v3float_uint_2
-         %65 = OpConstantNull %_arr_v3float_uint_2
-     %uint_0 = OpConstant %uint 0
+        %140 = OpConstantNull %_arr_v3float_uint_2
     %uint_34 = OpConstant %uint 34
-%_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
 %_ptr_Function_v3float = OpTypePointer Function %v3float
-     %uint_1 = OpConstant %uint 1
-         %78 = OpTypeFunction %void %Inner
+        %150 = OpTypeFunction %void %Inner
     %uint_36 = OpConstant %uint 36
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
-         %92 = OpTypeFunction %void %_arr_uint_uint_1 %Inner
+        %164 = OpTypeFunction %void %_arr_uint_uint_1 %Inner
     %uint_37 = OpConstant %uint 37
-         %99 = OpConstantNull %int
-        %109 = OpTypeFunction %void %_arr_Inner_uint_4
+        %180 = OpTypeFunction %void %_arr_Inner_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-        %125 = OpConstantNull %_arr_Inner_uint_4
+        %196 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
-        %135 = OpTypeFunction %void
-        %139 = OpConstantNull %float
+        %206 = OpTypeFunction %void
+        %210 = OpConstantNull %float
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-     %uint_3 = OpConstant %uint 3
-        %145 = OpConstantNull %half
+        %215 = OpConstantNull %half
 %_ptr_StorageBuffer_v2float = OpTypePointer StorageBuffer %v2float
-        %148 = OpConstantNull %v2float
+        %218 = OpConstantNull %v2float
      %uint_5 = OpConstant %uint 5
 %_ptr_StorageBuffer_v2int = OpTypePointer StorageBuffer %v2int
-        %152 = OpConstantNull %v2int
+        %222 = OpConstantNull %v2int
      %uint_6 = OpConstant %uint 6
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
-        %156 = OpConstantNull %v2uint
+        %226 = OpConstantNull %v2uint
      %uint_7 = OpConstant %uint 7
 %_ptr_StorageBuffer_v2half = OpTypePointer StorageBuffer %v2half
-        %160 = OpConstantNull %v2half
+        %230 = OpConstantNull %v2half
      %uint_8 = OpConstant %uint 8
-        %163 = OpConstantNull %v3float
+        %233 = OpConstantNull %v3float
      %uint_9 = OpConstant %uint 9
 %_ptr_StorageBuffer_v3int = OpTypePointer StorageBuffer %v3int
-        %167 = OpConstantNull %v3int
+        %237 = OpConstantNull %v3int
     %uint_10 = OpConstant %uint 10
 %_ptr_StorageBuffer_v3uint = OpTypePointer StorageBuffer %v3uint
-        %171 = OpConstantNull %v3uint
+        %241 = OpConstantNull %v3uint
     %uint_11 = OpConstant %uint 11
-%_ptr_StorageBuffer_v3half = OpTypePointer StorageBuffer %v3half
-        %175 = OpConstantNull %v3half
+        %244 = OpConstantNull %v3half
     %uint_12 = OpConstant %uint 12
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-        %179 = OpConstantNull %v4float
+        %248 = OpConstantNull %v4float
     %uint_13 = OpConstant %uint 13
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-        %183 = OpConstantNull %v4int
+        %252 = OpConstantNull %v4int
     %uint_14 = OpConstant %uint 14
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
-        %187 = OpConstantNull %v4uint
+        %256 = OpConstantNull %v4uint
     %uint_15 = OpConstant %uint 15
 %_ptr_StorageBuffer_v4half = OpTypePointer StorageBuffer %v4half
-        %191 = OpConstantNull %v4half
+        %260 = OpConstantNull %v4half
     %uint_16 = OpConstant %uint 16
 %_ptr_StorageBuffer_mat2v2float = OpTypePointer StorageBuffer %mat2v2float
-        %195 = OpConstantNull %mat2v2float
-    %uint_17 = OpConstant %uint 17
-%_ptr_StorageBuffer_mat2v3float = OpTypePointer StorageBuffer %mat2v3float
-        %199 = OpConstantNull %mat2v3float
+        %264 = OpConstantNull %mat2v2float
+        %266 = OpConstantNull %mat2v3float
     %uint_18 = OpConstant %uint 18
 %_ptr_StorageBuffer_mat2v4float = OpTypePointer StorageBuffer %mat2v4float
-        %203 = OpConstantNull %mat2v4float
+        %270 = OpConstantNull %mat2v4float
     %uint_19 = OpConstant %uint 19
 %_ptr_StorageBuffer_mat3v2float = OpTypePointer StorageBuffer %mat3v2float
-        %207 = OpConstantNull %mat3v2float
-    %uint_20 = OpConstant %uint 20
-%_ptr_StorageBuffer_mat3v3float = OpTypePointer StorageBuffer %mat3v3float
-        %211 = OpConstantNull %mat3v3float
+        %274 = OpConstantNull %mat3v2float
+        %276 = OpConstantNull %mat3v3float
     %uint_21 = OpConstant %uint 21
 %_ptr_StorageBuffer_mat3v4float = OpTypePointer StorageBuffer %mat3v4float
-        %215 = OpConstantNull %mat3v4float
+        %280 = OpConstantNull %mat3v4float
     %uint_22 = OpConstant %uint 22
 %_ptr_StorageBuffer_mat4v2float = OpTypePointer StorageBuffer %mat4v2float
-        %219 = OpConstantNull %mat4v2float
-    %uint_23 = OpConstant %uint 23
-%_ptr_StorageBuffer_mat4v3float = OpTypePointer StorageBuffer %mat4v3float
-        %223 = OpConstantNull %mat4v3float
+        %284 = OpConstantNull %mat4v2float
+        %286 = OpConstantNull %mat4v3float
     %uint_24 = OpConstant %uint 24
 %_ptr_StorageBuffer_mat4v4float = OpTypePointer StorageBuffer %mat4v4float
-        %227 = OpConstantNull %mat4v4float
+        %290 = OpConstantNull %mat4v4float
     %uint_25 = OpConstant %uint 25
 %_ptr_StorageBuffer_mat2v2half = OpTypePointer StorageBuffer %mat2v2half
-        %231 = OpConstantNull %mat2v2half
-    %uint_26 = OpConstant %uint 26
-%_ptr_StorageBuffer_mat2v3half = OpTypePointer StorageBuffer %mat2v3half
-        %235 = OpConstantNull %mat2v3half
+        %294 = OpConstantNull %mat2v2half
+        %296 = OpConstantNull %mat2v3half
     %uint_27 = OpConstant %uint 27
 %_ptr_StorageBuffer_mat2v4half = OpTypePointer StorageBuffer %mat2v4half
-        %239 = OpConstantNull %mat2v4half
+        %300 = OpConstantNull %mat2v4half
     %uint_28 = OpConstant %uint 28
 %_ptr_StorageBuffer_mat3v2half = OpTypePointer StorageBuffer %mat3v2half
-        %243 = OpConstantNull %mat3v2half
-    %uint_29 = OpConstant %uint 29
-%_ptr_StorageBuffer_mat3v3half = OpTypePointer StorageBuffer %mat3v3half
-        %247 = OpConstantNull %mat3v3half
+        %304 = OpConstantNull %mat3v2half
+        %306 = OpConstantNull %mat3v3half
     %uint_30 = OpConstant %uint 30
 %_ptr_StorageBuffer_mat3v4half = OpTypePointer StorageBuffer %mat3v4half
-        %251 = OpConstantNull %mat3v4half
+        %310 = OpConstantNull %mat3v4half
     %uint_31 = OpConstant %uint 31
 %_ptr_StorageBuffer_mat4v2half = OpTypePointer StorageBuffer %mat4v2half
-        %255 = OpConstantNull %mat4v2half
-    %uint_32 = OpConstant %uint 32
-%_ptr_StorageBuffer_mat4v3half = OpTypePointer StorageBuffer %mat4v3half
-        %259 = OpConstantNull %mat4v3half
+        %314 = OpConstantNull %mat4v2half
+        %316 = OpConstantNull %mat4v3half
     %uint_33 = OpConstant %uint 33
 %_ptr_StorageBuffer_mat4v4half = OpTypePointer StorageBuffer %mat4v4half
-        %263 = OpConstantNull %mat4v4half
+        %320 = OpConstantNull %mat4v4half
     %uint_35 = OpConstant %uint 35
 %_ptr_StorageBuffer__arr_mat4v2half_uint_2 = OpTypePointer StorageBuffer %_arr_mat4v2half_uint_2
-        %268 = OpConstantNull %_arr_mat4v2half_uint_2
-        %270 = OpConstantNull %Inner
-%assign_and_preserve_padding_sb_arr2_vec3_f32 = OpFunction %void None %45
-      %value = OpFunctionParameter %_arr_v3float_uint_2
+        %325 = OpConstantNull %_arr_mat4v2half_uint_2
+        %327 = OpConstantNull %Inner
+%assign_and_preserve_padding_sb_mat2x3_f32 = OpFunction %void None %45
+      %value = OpFunctionParameter %mat2v3float
          %49 = OpLabel
-          %i = OpVariable %_ptr_Function_uint Function %50
-%var_for_index = OpVariable %_ptr_Function__arr_v3float_uint_2 Function %65
-               OpStore %i %50
-               OpBranch %53
-         %53 = OpLabel
-               OpLoopMerge %54 %55 None
-               OpBranch %56
-         %56 = OpLabel
-         %58 = OpLoad %uint %i
-         %59 = OpULessThan %bool %58 %uint_2
-         %57 = OpLogicalNot %bool %59
-               OpSelectionMerge %61 None
-               OpBranchConditional %57 %62 %61
-         %62 = OpLabel
-               OpBranch %54
-         %61 = OpLabel
-               OpStore %var_for_index %value
-         %68 = OpLoad %uint %i
-         %70 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %uint_34 %68
-         %71 = OpLoad %uint %i
-         %73 = OpAccessChain %_ptr_Function_v3float %var_for_index %71
-         %74 = OpLoad %v3float %73
-               OpStore %70 %74
-               OpBranch %55
-         %55 = OpLabel
-         %75 = OpLoad %uint %i
-         %77 = OpIAdd %uint %75 %uint_1
-               OpStore %i %77
-               OpBranch %53
-         %54 = OpLabel
+         %54 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %uint_17 %52
+         %56 = OpCompositeExtract %v3float %value 0
+               OpStore %54 %56
+         %58 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %uint_17 %int_1
+         %60 = OpCompositeExtract %v3float %value 1
+               OpStore %58 %60
                OpReturn
                OpFunctionEnd
-%assign_and_preserve_padding_1_sb_struct_inner = OpFunction %void None %78
-    %value_0 = OpFunctionParameter %Inner
-         %81 = OpLabel
-         %84 = OpAccessChain %_ptr_StorageBuffer_int %sb %uint_0 %uint_36 %uint_0
-         %85 = OpCompositeExtract %int %value_0 0
-               OpStore %84 %85
-         %87 = OpAccessChain %_ptr_StorageBuffer_float %sb %uint_0 %uint_36 %uint_1
-         %88 = OpCompositeExtract %float %value_0 1
-               OpStore %87 %88
-         %90 = OpAccessChain %_ptr_StorageBuffer_half %sb %uint_0 %uint_36 %uint_2
-         %91 = OpCompositeExtract %half %value_0 2
-               OpStore %90 %91
+%assign_and_preserve_padding_1_sb_mat3x3_f32 = OpFunction %void None %61
+    %value_0 = OpFunctionParameter %mat3v3float
+         %64 = OpLabel
+         %66 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %uint_20 %52
+         %67 = OpCompositeExtract %v3float %value_0 0
+               OpStore %66 %67
+         %68 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %uint_20 %int_1
+         %69 = OpCompositeExtract %v3float %value_0 1
+               OpStore %68 %69
+         %71 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %uint_20 %int_2
+         %72 = OpCompositeExtract %v3float %value_0 2
+               OpStore %71 %72
                OpReturn
                OpFunctionEnd
-%assign_and_preserve_padding_1_sb_array_struct_inner_X = OpFunction %void None %92
-       %dest = OpFunctionParameter %_arr_uint_uint_1
-    %value_1 = OpFunctionParameter %Inner
-         %97 = OpLabel
-        %100 = OpCompositeExtract %uint %dest 0
-        %101 = OpAccessChain %_ptr_StorageBuffer_int %sb %uint_0 %uint_37 %100 %uint_0
-        %102 = OpCompositeExtract %int %value_1 0
-               OpStore %101 %102
-        %103 = OpCompositeExtract %uint %dest 0
-        %104 = OpAccessChain %_ptr_StorageBuffer_float %sb %uint_0 %uint_37 %103 %uint_1
-        %105 = OpCompositeExtract %float %value_1 1
-               OpStore %104 %105
-        %106 = OpCompositeExtract %uint %dest 0
-        %107 = OpAccessChain %_ptr_StorageBuffer_half %sb %uint_0 %uint_37 %106 %uint_2
-        %108 = OpCompositeExtract %half %value_1 2
+%assign_and_preserve_padding_2_sb_mat4x3_f32 = OpFunction %void None %73
+    %value_1 = OpFunctionParameter %mat4v3float
+         %76 = OpLabel
+         %78 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %uint_23 %52
+         %79 = OpCompositeExtract %v3float %value_1 0
+               OpStore %78 %79
+         %80 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %uint_23 %int_1
+         %81 = OpCompositeExtract %v3float %value_1 1
+               OpStore %80 %81
+         %82 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %uint_23 %int_2
+         %83 = OpCompositeExtract %v3float %value_1 2
+               OpStore %82 %83
+         %85 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %uint_23 %int_3
+         %87 = OpCompositeExtract %v3float %value_1 3
+               OpStore %85 %87
+               OpReturn
+               OpFunctionEnd
+%assign_and_preserve_padding_3_sb_mat2x3_f16 = OpFunction %void None %88
+    %value_2 = OpFunctionParameter %mat2v3half
+         %91 = OpLabel
+         %94 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %uint_26 %52
+         %95 = OpCompositeExtract %v3half %value_2 0
+               OpStore %94 %95
+         %96 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %uint_26 %int_1
+         %97 = OpCompositeExtract %v3half %value_2 1
+               OpStore %96 %97
+               OpReturn
+               OpFunctionEnd
+%assign_and_preserve_padding_4_sb_mat3x3_f16 = OpFunction %void None %98
+    %value_3 = OpFunctionParameter %mat3v3half
+        %101 = OpLabel
+        %103 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %uint_29 %52
+        %104 = OpCompositeExtract %v3half %value_3 0
+               OpStore %103 %104
+        %105 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %uint_29 %int_1
+        %106 = OpCompositeExtract %v3half %value_3 1
+               OpStore %105 %106
+        %107 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %uint_29 %int_2
+        %108 = OpCompositeExtract %v3half %value_3 2
                OpStore %107 %108
                OpReturn
                OpFunctionEnd
-%assign_and_preserve_padding_2_sb_array_struct_inner = OpFunction %void None %109
-    %value_2 = OpFunctionParameter %_arr_Inner_uint_4
+%assign_and_preserve_padding_5_sb_mat4x3_f16 = OpFunction %void None %109
+    %value_4 = OpFunctionParameter %mat4v3half
         %112 = OpLabel
-        %i_0 = OpVariable %_ptr_Function_uint Function %50
-%var_for_index_1 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %125
-               OpStore %i_0 %50
-               OpBranch %114
-        %114 = OpLabel
-               OpLoopMerge %115 %116 None
-               OpBranch %117
-        %117 = OpLabel
-        %119 = OpLoad %uint %i_0
-        %120 = OpULessThan %bool %119 %uint_4
-        %118 = OpLogicalNot %bool %120
-               OpSelectionMerge %121 None
-               OpBranchConditional %118 %122 %121
-        %122 = OpLabel
-               OpBranch %115
-        %121 = OpLabel
-               OpStore %var_for_index_1 %value_2
-        %127 = OpLoad %uint %i_0
-        %128 = OpCompositeConstruct %_arr_uint_uint_1 %127
-        %129 = OpLoad %uint %i_0
-        %131 = OpAccessChain %_ptr_Function_Inner %var_for_index_1 %129
-        %132 = OpLoad %Inner %131
-        %126 = OpFunctionCall %void %assign_and_preserve_padding_1_sb_array_struct_inner_X %128 %132
-               OpBranch %116
-        %116 = OpLabel
-        %133 = OpLoad %uint %i_0
-        %134 = OpIAdd %uint %133 %uint_1
-               OpStore %i_0 %134
-               OpBranch %114
-        %115 = OpLabel
+        %114 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %uint_32 %52
+        %115 = OpCompositeExtract %v3half %value_4 0
+               OpStore %114 %115
+        %116 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %uint_32 %int_1
+        %117 = OpCompositeExtract %v3half %value_4 1
+               OpStore %116 %117
+        %118 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %uint_32 %int_2
+        %119 = OpCompositeExtract %v3half %value_4 2
+               OpStore %118 %119
+        %120 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %uint_32 %int_3
+        %121 = OpCompositeExtract %v3half %value_4 3
+               OpStore %120 %121
                OpReturn
                OpFunctionEnd
-       %main = OpFunction %void None %135
+%assign_and_preserve_padding_6_sb_arr2_vec3_f32 = OpFunction %void None %122
+    %value_5 = OpFunctionParameter %_arr_v3float_uint_2
+        %125 = OpLabel
+          %i = OpVariable %_ptr_Function_uint Function %55
+%var_for_index = OpVariable %_ptr_Function__arr_v3float_uint_2 Function %140
+               OpStore %i %55
+               OpBranch %128
+        %128 = OpLabel
+               OpLoopMerge %129 %130 None
+               OpBranch %131
+        %131 = OpLabel
+        %133 = OpLoad %uint %i
+        %134 = OpULessThan %bool %133 %uint_2
+        %132 = OpLogicalNot %bool %134
+               OpSelectionMerge %136 None
+               OpBranchConditional %132 %137 %136
         %137 = OpLabel
-        %138 = OpAccessChain %_ptr_StorageBuffer_float %sb %uint_0 %uint_0
-               OpStore %138 %139
-        %140 = OpAccessChain %_ptr_StorageBuffer_int %sb %uint_0 %uint_1
-               OpStore %140 %99
-        %142 = OpAccessChain %_ptr_StorageBuffer_uint %sb %uint_0 %uint_2
-               OpStore %142 %50
-        %144 = OpAccessChain %_ptr_StorageBuffer_half %sb %uint_0 %uint_3
-               OpStore %144 %145
-        %147 = OpAccessChain %_ptr_StorageBuffer_v2float %sb %uint_0 %uint_4
-               OpStore %147 %148
-        %151 = OpAccessChain %_ptr_StorageBuffer_v2int %sb %uint_0 %uint_5
-               OpStore %151 %152
-        %155 = OpAccessChain %_ptr_StorageBuffer_v2uint %sb %uint_0 %uint_6
-               OpStore %155 %156
-        %159 = OpAccessChain %_ptr_StorageBuffer_v2half %sb %uint_0 %uint_7
+               OpBranch %129
+        %136 = OpLabel
+               OpStore %var_for_index %value_5
+        %142 = OpLoad %uint %i
+        %143 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %uint_34 %142
+        %144 = OpLoad %uint %i
+        %146 = OpAccessChain %_ptr_Function_v3float %var_for_index %144
+        %147 = OpLoad %v3float %146
+               OpStore %143 %147
+               OpBranch %130
+        %130 = OpLabel
+        %148 = OpLoad %uint %i
+        %149 = OpIAdd %uint %148 %uint_1
+               OpStore %i %149
+               OpBranch %128
+        %129 = OpLabel
+               OpReturn
+               OpFunctionEnd
+%assign_and_preserve_padding_7_sb_struct_inner = OpFunction %void None %150
+    %value_6 = OpFunctionParameter %Inner
+        %153 = OpLabel
+        %156 = OpAccessChain %_ptr_StorageBuffer_int %sb %uint_0 %uint_36 %uint_0
+        %157 = OpCompositeExtract %int %value_6 0
+               OpStore %156 %157
+        %159 = OpAccessChain %_ptr_StorageBuffer_float %sb %uint_0 %uint_36 %uint_1
+        %160 = OpCompositeExtract %float %value_6 1
                OpStore %159 %160
-        %162 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %uint_8
+        %162 = OpAccessChain %_ptr_StorageBuffer_half %sb %uint_0 %uint_36 %uint_2
+        %163 = OpCompositeExtract %half %value_6 2
                OpStore %162 %163
-        %166 = OpAccessChain %_ptr_StorageBuffer_v3int %sb %uint_0 %uint_9
-               OpStore %166 %167
-        %170 = OpAccessChain %_ptr_StorageBuffer_v3uint %sb %uint_0 %uint_10
-               OpStore %170 %171
-        %174 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %uint_11
-               OpStore %174 %175
-        %178 = OpAccessChain %_ptr_StorageBuffer_v4float %sb %uint_0 %uint_12
+               OpReturn
+               OpFunctionEnd
+%assign_and_preserve_padding_7_sb_array_struct_inner_X = OpFunction %void None %164
+       %dest = OpFunctionParameter %_arr_uint_uint_1
+    %value_7 = OpFunctionParameter %Inner
+        %169 = OpLabel
+        %171 = OpCompositeExtract %uint %dest 0
+        %172 = OpAccessChain %_ptr_StorageBuffer_int %sb %uint_0 %uint_37 %171 %uint_0
+        %173 = OpCompositeExtract %int %value_7 0
+               OpStore %172 %173
+        %174 = OpCompositeExtract %uint %dest 0
+        %175 = OpAccessChain %_ptr_StorageBuffer_float %sb %uint_0 %uint_37 %174 %uint_1
+        %176 = OpCompositeExtract %float %value_7 1
+               OpStore %175 %176
+        %177 = OpCompositeExtract %uint %dest 0
+        %178 = OpAccessChain %_ptr_StorageBuffer_half %sb %uint_0 %uint_37 %177 %uint_2
+        %179 = OpCompositeExtract %half %value_7 2
                OpStore %178 %179
-        %182 = OpAccessChain %_ptr_StorageBuffer_v4int %sb %uint_0 %uint_13
-               OpStore %182 %183
-        %186 = OpAccessChain %_ptr_StorageBuffer_v4uint %sb %uint_0 %uint_14
-               OpStore %186 %187
-        %190 = OpAccessChain %_ptr_StorageBuffer_v4half %sb %uint_0 %uint_15
-               OpStore %190 %191
-        %194 = OpAccessChain %_ptr_StorageBuffer_mat2v2float %sb %uint_0 %uint_16
-               OpStore %194 %195
-        %198 = OpAccessChain %_ptr_StorageBuffer_mat2v3float %sb %uint_0 %uint_17
-               OpStore %198 %199
-        %202 = OpAccessChain %_ptr_StorageBuffer_mat2v4float %sb %uint_0 %uint_18
-               OpStore %202 %203
-        %206 = OpAccessChain %_ptr_StorageBuffer_mat3v2float %sb %uint_0 %uint_19
-               OpStore %206 %207
-        %210 = OpAccessChain %_ptr_StorageBuffer_mat3v3float %sb %uint_0 %uint_20
-               OpStore %210 %211
-        %214 = OpAccessChain %_ptr_StorageBuffer_mat3v4float %sb %uint_0 %uint_21
+               OpReturn
+               OpFunctionEnd
+%assign_and_preserve_padding_8_sb_array_struct_inner = OpFunction %void None %180
+    %value_8 = OpFunctionParameter %_arr_Inner_uint_4
+        %183 = OpLabel
+        %i_0 = OpVariable %_ptr_Function_uint Function %55
+%var_for_index_1 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %196
+               OpStore %i_0 %55
+               OpBranch %185
+        %185 = OpLabel
+               OpLoopMerge %186 %187 None
+               OpBranch %188
+        %188 = OpLabel
+        %190 = OpLoad %uint %i_0
+        %191 = OpULessThan %bool %190 %uint_4
+        %189 = OpLogicalNot %bool %191
+               OpSelectionMerge %192 None
+               OpBranchConditional %189 %193 %192
+        %193 = OpLabel
+               OpBranch %186
+        %192 = OpLabel
+               OpStore %var_for_index_1 %value_8
+        %198 = OpLoad %uint %i_0
+        %199 = OpCompositeConstruct %_arr_uint_uint_1 %198
+        %200 = OpLoad %uint %i_0
+        %202 = OpAccessChain %_ptr_Function_Inner %var_for_index_1 %200
+        %203 = OpLoad %Inner %202
+        %197 = OpFunctionCall %void %assign_and_preserve_padding_7_sb_array_struct_inner_X %199 %203
+               OpBranch %187
+        %187 = OpLabel
+        %204 = OpLoad %uint %i_0
+        %205 = OpIAdd %uint %204 %uint_1
+               OpStore %i_0 %205
+               OpBranch %185
+        %186 = OpLabel
+               OpReturn
+               OpFunctionEnd
+       %main = OpFunction %void None %206
+        %208 = OpLabel
+        %209 = OpAccessChain %_ptr_StorageBuffer_float %sb %uint_0 %uint_0
+               OpStore %209 %210
+        %211 = OpAccessChain %_ptr_StorageBuffer_int %sb %uint_0 %uint_1
+               OpStore %211 %52
+        %213 = OpAccessChain %_ptr_StorageBuffer_uint %sb %uint_0 %uint_2
+               OpStore %213 %55
+        %214 = OpAccessChain %_ptr_StorageBuffer_half %sb %uint_0 %uint_3
                OpStore %214 %215
-        %218 = OpAccessChain %_ptr_StorageBuffer_mat4v2float %sb %uint_0 %uint_22
-               OpStore %218 %219
-        %222 = OpAccessChain %_ptr_StorageBuffer_mat4v3float %sb %uint_0 %uint_23
-               OpStore %222 %223
-        %226 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %sb %uint_0 %uint_24
-               OpStore %226 %227
-        %230 = OpAccessChain %_ptr_StorageBuffer_mat2v2half %sb %uint_0 %uint_25
-               OpStore %230 %231
-        %234 = OpAccessChain %_ptr_StorageBuffer_mat2v3half %sb %uint_0 %uint_26
-               OpStore %234 %235
-        %238 = OpAccessChain %_ptr_StorageBuffer_mat2v4half %sb %uint_0 %uint_27
-               OpStore %238 %239
-        %242 = OpAccessChain %_ptr_StorageBuffer_mat3v2half %sb %uint_0 %uint_28
-               OpStore %242 %243
-        %246 = OpAccessChain %_ptr_StorageBuffer_mat3v3half %sb %uint_0 %uint_29
-               OpStore %246 %247
-        %250 = OpAccessChain %_ptr_StorageBuffer_mat3v4half %sb %uint_0 %uint_30
-               OpStore %250 %251
-        %254 = OpAccessChain %_ptr_StorageBuffer_mat4v2half %sb %uint_0 %uint_31
-               OpStore %254 %255
-        %258 = OpAccessChain %_ptr_StorageBuffer_mat4v3half %sb %uint_0 %uint_32
-               OpStore %258 %259
-        %262 = OpAccessChain %_ptr_StorageBuffer_mat4v4half %sb %uint_0 %uint_33
-               OpStore %262 %263
-        %264 = OpFunctionCall %void %assign_and_preserve_padding_sb_arr2_vec3_f32 %65
-        %267 = OpAccessChain %_ptr_StorageBuffer__arr_mat4v2half_uint_2 %sb %uint_0 %uint_35
-               OpStore %267 %268
-        %269 = OpFunctionCall %void %assign_and_preserve_padding_1_sb_struct_inner %270
-        %271 = OpFunctionCall %void %assign_and_preserve_padding_2_sb_array_struct_inner %125
+        %217 = OpAccessChain %_ptr_StorageBuffer_v2float %sb %uint_0 %uint_4
+               OpStore %217 %218
+        %221 = OpAccessChain %_ptr_StorageBuffer_v2int %sb %uint_0 %uint_5
+               OpStore %221 %222
+        %225 = OpAccessChain %_ptr_StorageBuffer_v2uint %sb %uint_0 %uint_6
+               OpStore %225 %226
+        %229 = OpAccessChain %_ptr_StorageBuffer_v2half %sb %uint_0 %uint_7
+               OpStore %229 %230
+        %232 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %uint_8
+               OpStore %232 %233
+        %236 = OpAccessChain %_ptr_StorageBuffer_v3int %sb %uint_0 %uint_9
+               OpStore %236 %237
+        %240 = OpAccessChain %_ptr_StorageBuffer_v3uint %sb %uint_0 %uint_10
+               OpStore %240 %241
+        %243 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %uint_11
+               OpStore %243 %244
+        %247 = OpAccessChain %_ptr_StorageBuffer_v4float %sb %uint_0 %uint_12
+               OpStore %247 %248
+        %251 = OpAccessChain %_ptr_StorageBuffer_v4int %sb %uint_0 %uint_13
+               OpStore %251 %252
+        %255 = OpAccessChain %_ptr_StorageBuffer_v4uint %sb %uint_0 %uint_14
+               OpStore %255 %256
+        %259 = OpAccessChain %_ptr_StorageBuffer_v4half %sb %uint_0 %uint_15
+               OpStore %259 %260
+        %263 = OpAccessChain %_ptr_StorageBuffer_mat2v2float %sb %uint_0 %uint_16
+               OpStore %263 %264
+        %265 = OpFunctionCall %void %assign_and_preserve_padding_sb_mat2x3_f32 %266
+        %269 = OpAccessChain %_ptr_StorageBuffer_mat2v4float %sb %uint_0 %uint_18
+               OpStore %269 %270
+        %273 = OpAccessChain %_ptr_StorageBuffer_mat3v2float %sb %uint_0 %uint_19
+               OpStore %273 %274
+        %275 = OpFunctionCall %void %assign_and_preserve_padding_1_sb_mat3x3_f32 %276
+        %279 = OpAccessChain %_ptr_StorageBuffer_mat3v4float %sb %uint_0 %uint_21
+               OpStore %279 %280
+        %283 = OpAccessChain %_ptr_StorageBuffer_mat4v2float %sb %uint_0 %uint_22
+               OpStore %283 %284
+        %285 = OpFunctionCall %void %assign_and_preserve_padding_2_sb_mat4x3_f32 %286
+        %289 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %sb %uint_0 %uint_24
+               OpStore %289 %290
+        %293 = OpAccessChain %_ptr_StorageBuffer_mat2v2half %sb %uint_0 %uint_25
+               OpStore %293 %294
+        %295 = OpFunctionCall %void %assign_and_preserve_padding_3_sb_mat2x3_f16 %296
+        %299 = OpAccessChain %_ptr_StorageBuffer_mat2v4half %sb %uint_0 %uint_27
+               OpStore %299 %300
+        %303 = OpAccessChain %_ptr_StorageBuffer_mat3v2half %sb %uint_0 %uint_28
+               OpStore %303 %304
+        %305 = OpFunctionCall %void %assign_and_preserve_padding_4_sb_mat3x3_f16 %306
+        %309 = OpAccessChain %_ptr_StorageBuffer_mat3v4half %sb %uint_0 %uint_30
+               OpStore %309 %310
+        %313 = OpAccessChain %_ptr_StorageBuffer_mat4v2half %sb %uint_0 %uint_31
+               OpStore %313 %314
+        %315 = OpFunctionCall %void %assign_and_preserve_padding_5_sb_mat4x3_f16 %316
+        %319 = OpAccessChain %_ptr_StorageBuffer_mat4v4half %sb %uint_0 %uint_33
+               OpStore %319 %320
+        %321 = OpFunctionCall %void %assign_and_preserve_padding_6_sb_arr2_vec3_f32 %140
+        %324 = OpAccessChain %_ptr_StorageBuffer__arr_mat4v2half_uint_2 %sb %uint_0 %uint_35
+               OpStore %324 %325
+        %326 = OpFunctionCall %void %assign_and_preserve_padding_7_sb_struct_inner %327
+        %328 = OpFunctionCall %void %assign_and_preserve_padding_8_sb_array_struct_inner %196
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/storage/types/mat2x3_f16.wgsl.expected.glsl b/test/tint/buffer/storage/types/mat2x3_f16.wgsl.expected.glsl
index 6bed36f..8c1e7743 100644
--- a/test/tint/buffer/storage/types/mat2x3_f16.wgsl.expected.glsl
+++ b/test/tint/buffer/storage/types/mat2x3_f16.wgsl.expected.glsl
@@ -9,8 +9,13 @@
   f16mat2x3 inner;
 } tint_symbol_1;
 
+void assign_and_preserve_padding_tint_symbol_1(f16mat2x3 value) {
+  tint_symbol_1.inner[0] = value[0u];
+  tint_symbol_1.inner[1] = value[1u];
+}
+
 void tint_symbol_2() {
-  tint_symbol_1.inner = tint_symbol.inner;
+  assign_and_preserve_padding_tint_symbol_1(tint_symbol.inner);
 }
 
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/buffer/storage/types/mat2x3_f16.wgsl.expected.msl b/test/tint/buffer/storage/types/mat2x3_f16.wgsl.expected.msl
index 81af92d..a79d9bb 100644
--- a/test/tint/buffer/storage/types/mat2x3_f16.wgsl.expected.msl
+++ b/test/tint/buffer/storage/types/mat2x3_f16.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+void assign_and_preserve_padding(device half2x3* const dest, half2x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+}
+
 kernel void tint_symbol(device half2x3* tint_symbol_1 [[buffer(0)]], const device half2x3* tint_symbol_2 [[buffer(1)]]) {
-  *(tint_symbol_1) = *(tint_symbol_2);
+  assign_and_preserve_padding(tint_symbol_1, *(tint_symbol_2));
   return;
 }
 
diff --git a/test/tint/buffer/storage/types/mat2x3_f16.wgsl.expected.spvasm b/test/tint/buffer/storage/types/mat2x3_f16.wgsl.expected.spvasm
index 5ddb847..081d373 100644
--- a/test/tint/buffer/storage/types/mat2x3_f16.wgsl.expected.spvasm
+++ b/test/tint/buffer/storage/types/mat2x3_f16.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 18
+; Bound: 32
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -15,6 +15,8 @@
                OpMemberName %in_block 0 "inner"
                OpName %in "in"
                OpName %out "out"
+               OpName %assign_and_preserve_padding_out "assign_and_preserve_padding_out"
+               OpName %value "value"
                OpName %main "main"
                OpDecorate %in_block Block
                OpMemberDecorate %in_block 0 Offset 0
@@ -33,15 +35,32 @@
          %in = OpVariable %_ptr_StorageBuffer_in_block StorageBuffer
         %out = OpVariable %_ptr_StorageBuffer_in_block StorageBuffer
        %void = OpTypeVoid
-          %8 = OpTypeFunction %void
+          %8 = OpTypeFunction %void %mat2v3half
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
+        %int = OpTypeInt 32 1
+         %16 = OpConstantNull %int
+%_ptr_StorageBuffer_v3half = OpTypePointer StorageBuffer %v3half
+         %19 = OpConstantNull %uint
+      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
+         %25 = OpTypeFunction %void
 %_ptr_StorageBuffer_mat2v3half = OpTypePointer StorageBuffer %mat2v3half
-       %main = OpFunction %void None %8
-         %11 = OpLabel
-         %15 = OpAccessChain %_ptr_StorageBuffer_mat2v3half %out %uint_0
-         %16 = OpAccessChain %_ptr_StorageBuffer_mat2v3half %in %uint_0
-         %17 = OpLoad %mat2v3half %16
-               OpStore %15 %17
+%assign_and_preserve_padding_out = OpFunction %void None %8
+      %value = OpFunctionParameter %mat2v3half
+         %12 = OpLabel
+         %18 = OpAccessChain %_ptr_StorageBuffer_v3half %out %uint_0 %16
+         %20 = OpCompositeExtract %v3half %value 0
+               OpStore %18 %20
+         %22 = OpAccessChain %_ptr_StorageBuffer_v3half %out %uint_0 %int_1
+         %24 = OpCompositeExtract %v3half %value 1
+               OpStore %22 %24
+               OpReturn
+               OpFunctionEnd
+       %main = OpFunction %void None %25
+         %27 = OpLabel
+         %30 = OpAccessChain %_ptr_StorageBuffer_mat2v3half %in %uint_0
+         %31 = OpLoad %mat2v3half %30
+         %28 = OpFunctionCall %void %assign_and_preserve_padding_out %31
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/storage/types/mat2x3_f32.wgsl.expected.glsl b/test/tint/buffer/storage/types/mat2x3_f32.wgsl.expected.glsl
index 8112c5d..daf1847 100644
--- a/test/tint/buffer/storage/types/mat2x3_f32.wgsl.expected.glsl
+++ b/test/tint/buffer/storage/types/mat2x3_f32.wgsl.expected.glsl
@@ -8,8 +8,13 @@
   mat2x3 inner;
 } tint_symbol_1;
 
+void assign_and_preserve_padding_tint_symbol_1(mat2x3 value) {
+  tint_symbol_1.inner[0] = value[0u];
+  tint_symbol_1.inner[1] = value[1u];
+}
+
 void tint_symbol_2() {
-  tint_symbol_1.inner = tint_symbol.inner;
+  assign_and_preserve_padding_tint_symbol_1(tint_symbol.inner);
 }
 
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/buffer/storage/types/mat2x3_f32.wgsl.expected.msl b/test/tint/buffer/storage/types/mat2x3_f32.wgsl.expected.msl
index 16b1298..486563d 100644
--- a/test/tint/buffer/storage/types/mat2x3_f32.wgsl.expected.msl
+++ b/test/tint/buffer/storage/types/mat2x3_f32.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+void assign_and_preserve_padding(device float2x3* const dest, float2x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+}
+
 kernel void tint_symbol(device float2x3* tint_symbol_1 [[buffer(0)]], const device float2x3* tint_symbol_2 [[buffer(1)]]) {
-  *(tint_symbol_1) = *(tint_symbol_2);
+  assign_and_preserve_padding(tint_symbol_1, *(tint_symbol_2));
   return;
 }
 
diff --git a/test/tint/buffer/storage/types/mat2x3_f32.wgsl.expected.spvasm b/test/tint/buffer/storage/types/mat2x3_f32.wgsl.expected.spvasm
index 31ddb99..b82d922 100644
--- a/test/tint/buffer/storage/types/mat2x3_f32.wgsl.expected.spvasm
+++ b/test/tint/buffer/storage/types/mat2x3_f32.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 18
+; Bound: 32
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -11,6 +11,8 @@
                OpMemberName %in_block 0 "inner"
                OpName %in "in"
                OpName %out "out"
+               OpName %assign_and_preserve_padding_out "assign_and_preserve_padding_out"
+               OpName %value "value"
                OpName %main "main"
                OpDecorate %in_block Block
                OpMemberDecorate %in_block 0 Offset 0
@@ -29,15 +31,32 @@
          %in = OpVariable %_ptr_StorageBuffer_in_block StorageBuffer
         %out = OpVariable %_ptr_StorageBuffer_in_block StorageBuffer
        %void = OpTypeVoid
-          %8 = OpTypeFunction %void
+          %8 = OpTypeFunction %void %mat2v3float
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
+        %int = OpTypeInt 32 1
+         %16 = OpConstantNull %int
+%_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
+         %19 = OpConstantNull %uint
+      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
+         %25 = OpTypeFunction %void
 %_ptr_StorageBuffer_mat2v3float = OpTypePointer StorageBuffer %mat2v3float
-       %main = OpFunction %void None %8
-         %11 = OpLabel
-         %15 = OpAccessChain %_ptr_StorageBuffer_mat2v3float %out %uint_0
-         %16 = OpAccessChain %_ptr_StorageBuffer_mat2v3float %in %uint_0
-         %17 = OpLoad %mat2v3float %16
-               OpStore %15 %17
+%assign_and_preserve_padding_out = OpFunction %void None %8
+      %value = OpFunctionParameter %mat2v3float
+         %12 = OpLabel
+         %18 = OpAccessChain %_ptr_StorageBuffer_v3float %out %uint_0 %16
+         %20 = OpCompositeExtract %v3float %value 0
+               OpStore %18 %20
+         %22 = OpAccessChain %_ptr_StorageBuffer_v3float %out %uint_0 %int_1
+         %24 = OpCompositeExtract %v3float %value 1
+               OpStore %22 %24
+               OpReturn
+               OpFunctionEnd
+       %main = OpFunction %void None %25
+         %27 = OpLabel
+         %30 = OpAccessChain %_ptr_StorageBuffer_mat2v3float %in %uint_0
+         %31 = OpLoad %mat2v3float %30
+         %28 = OpFunctionCall %void %assign_and_preserve_padding_out %31
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/storage/types/mat3x3_f16.wgsl.expected.glsl b/test/tint/buffer/storage/types/mat3x3_f16.wgsl.expected.glsl
index 00509e6..ee6697f 100644
--- a/test/tint/buffer/storage/types/mat3x3_f16.wgsl.expected.glsl
+++ b/test/tint/buffer/storage/types/mat3x3_f16.wgsl.expected.glsl
@@ -9,8 +9,14 @@
   f16mat3 inner;
 } tint_symbol_1;
 
+void assign_and_preserve_padding_tint_symbol_1(f16mat3 value) {
+  tint_symbol_1.inner[0] = value[0u];
+  tint_symbol_1.inner[1] = value[1u];
+  tint_symbol_1.inner[2] = value[2u];
+}
+
 void tint_symbol_2() {
-  tint_symbol_1.inner = tint_symbol.inner;
+  assign_and_preserve_padding_tint_symbol_1(tint_symbol.inner);
 }
 
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/buffer/storage/types/mat3x3_f16.wgsl.expected.msl b/test/tint/buffer/storage/types/mat3x3_f16.wgsl.expected.msl
index e22bd15..69da6e0 100644
--- a/test/tint/buffer/storage/types/mat3x3_f16.wgsl.expected.msl
+++ b/test/tint/buffer/storage/types/mat3x3_f16.wgsl.expected.msl
@@ -1,8 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+void assign_and_preserve_padding(device half3x3* const dest, half3x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+}
+
 kernel void tint_symbol(device half3x3* tint_symbol_1 [[buffer(0)]], const device half3x3* tint_symbol_2 [[buffer(1)]]) {
-  *(tint_symbol_1) = *(tint_symbol_2);
+  assign_and_preserve_padding(tint_symbol_1, *(tint_symbol_2));
   return;
 }
 
diff --git a/test/tint/buffer/storage/types/mat3x3_f16.wgsl.expected.spvasm b/test/tint/buffer/storage/types/mat3x3_f16.wgsl.expected.spvasm
index ad8eff5..cc62811 100644
--- a/test/tint/buffer/storage/types/mat3x3_f16.wgsl.expected.spvasm
+++ b/test/tint/buffer/storage/types/mat3x3_f16.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 18
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -15,6 +15,8 @@
                OpMemberName %in_block 0 "inner"
                OpName %in "in"
                OpName %out "out"
+               OpName %assign_and_preserve_padding_out "assign_and_preserve_padding_out"
+               OpName %value "value"
                OpName %main "main"
                OpDecorate %in_block Block
                OpMemberDecorate %in_block 0 Offset 0
@@ -33,15 +35,37 @@
          %in = OpVariable %_ptr_StorageBuffer_in_block StorageBuffer
         %out = OpVariable %_ptr_StorageBuffer_in_block StorageBuffer
        %void = OpTypeVoid
-          %8 = OpTypeFunction %void
+          %8 = OpTypeFunction %void %mat3v3half
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
+        %int = OpTypeInt 32 1
+         %16 = OpConstantNull %int
+%_ptr_StorageBuffer_v3half = OpTypePointer StorageBuffer %v3half
+         %19 = OpConstantNull %uint
+      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
+      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
+         %29 = OpTypeFunction %void
 %_ptr_StorageBuffer_mat3v3half = OpTypePointer StorageBuffer %mat3v3half
-       %main = OpFunction %void None %8
-         %11 = OpLabel
-         %15 = OpAccessChain %_ptr_StorageBuffer_mat3v3half %out %uint_0
-         %16 = OpAccessChain %_ptr_StorageBuffer_mat3v3half %in %uint_0
-         %17 = OpLoad %mat3v3half %16
-               OpStore %15 %17
+%assign_and_preserve_padding_out = OpFunction %void None %8
+      %value = OpFunctionParameter %mat3v3half
+         %12 = OpLabel
+         %18 = OpAccessChain %_ptr_StorageBuffer_v3half %out %uint_0 %16
+         %20 = OpCompositeExtract %v3half %value 0
+               OpStore %18 %20
+         %22 = OpAccessChain %_ptr_StorageBuffer_v3half %out %uint_0 %int_1
+         %24 = OpCompositeExtract %v3half %value 1
+               OpStore %22 %24
+         %26 = OpAccessChain %_ptr_StorageBuffer_v3half %out %uint_0 %int_2
+         %28 = OpCompositeExtract %v3half %value 2
+               OpStore %26 %28
+               OpReturn
+               OpFunctionEnd
+       %main = OpFunction %void None %29
+         %31 = OpLabel
+         %34 = OpAccessChain %_ptr_StorageBuffer_mat3v3half %in %uint_0
+         %35 = OpLoad %mat3v3half %34
+         %32 = OpFunctionCall %void %assign_and_preserve_padding_out %35
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/storage/types/mat3x3_f32.wgsl.expected.glsl b/test/tint/buffer/storage/types/mat3x3_f32.wgsl.expected.glsl
index b6e12e5..c7842b7 100644
--- a/test/tint/buffer/storage/types/mat3x3_f32.wgsl.expected.glsl
+++ b/test/tint/buffer/storage/types/mat3x3_f32.wgsl.expected.glsl
@@ -8,8 +8,14 @@
   mat3 inner;
 } tint_symbol_1;
 
+void assign_and_preserve_padding_tint_symbol_1(mat3 value) {
+  tint_symbol_1.inner[0] = value[0u];
+  tint_symbol_1.inner[1] = value[1u];
+  tint_symbol_1.inner[2] = value[2u];
+}
+
 void tint_symbol_2() {
-  tint_symbol_1.inner = tint_symbol.inner;
+  assign_and_preserve_padding_tint_symbol_1(tint_symbol.inner);
 }
 
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/buffer/storage/types/mat3x3_f32.wgsl.expected.msl b/test/tint/buffer/storage/types/mat3x3_f32.wgsl.expected.msl
index c8db576..3054c1c 100644
--- a/test/tint/buffer/storage/types/mat3x3_f32.wgsl.expected.msl
+++ b/test/tint/buffer/storage/types/mat3x3_f32.wgsl.expected.msl
@@ -1,8 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+void assign_and_preserve_padding(device float3x3* const dest, float3x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+}
+
 kernel void tint_symbol(device float3x3* tint_symbol_1 [[buffer(0)]], const device float3x3* tint_symbol_2 [[buffer(1)]]) {
-  *(tint_symbol_1) = *(tint_symbol_2);
+  assign_and_preserve_padding(tint_symbol_1, *(tint_symbol_2));
   return;
 }
 
diff --git a/test/tint/buffer/storage/types/mat3x3_f32.wgsl.expected.spvasm b/test/tint/buffer/storage/types/mat3x3_f32.wgsl.expected.spvasm
index 278850e..2d564ac 100644
--- a/test/tint/buffer/storage/types/mat3x3_f32.wgsl.expected.spvasm
+++ b/test/tint/buffer/storage/types/mat3x3_f32.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 18
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -11,6 +11,8 @@
                OpMemberName %in_block 0 "inner"
                OpName %in "in"
                OpName %out "out"
+               OpName %assign_and_preserve_padding_out "assign_and_preserve_padding_out"
+               OpName %value "value"
                OpName %main "main"
                OpDecorate %in_block Block
                OpMemberDecorate %in_block 0 Offset 0
@@ -29,15 +31,37 @@
          %in = OpVariable %_ptr_StorageBuffer_in_block StorageBuffer
         %out = OpVariable %_ptr_StorageBuffer_in_block StorageBuffer
        %void = OpTypeVoid
-          %8 = OpTypeFunction %void
+          %8 = OpTypeFunction %void %mat3v3float
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
+        %int = OpTypeInt 32 1
+         %16 = OpConstantNull %int
+%_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
+         %19 = OpConstantNull %uint
+      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
+      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
+         %29 = OpTypeFunction %void
 %_ptr_StorageBuffer_mat3v3float = OpTypePointer StorageBuffer %mat3v3float
-       %main = OpFunction %void None %8
-         %11 = OpLabel
-         %15 = OpAccessChain %_ptr_StorageBuffer_mat3v3float %out %uint_0
-         %16 = OpAccessChain %_ptr_StorageBuffer_mat3v3float %in %uint_0
-         %17 = OpLoad %mat3v3float %16
-               OpStore %15 %17
+%assign_and_preserve_padding_out = OpFunction %void None %8
+      %value = OpFunctionParameter %mat3v3float
+         %12 = OpLabel
+         %18 = OpAccessChain %_ptr_StorageBuffer_v3float %out %uint_0 %16
+         %20 = OpCompositeExtract %v3float %value 0
+               OpStore %18 %20
+         %22 = OpAccessChain %_ptr_StorageBuffer_v3float %out %uint_0 %int_1
+         %24 = OpCompositeExtract %v3float %value 1
+               OpStore %22 %24
+         %26 = OpAccessChain %_ptr_StorageBuffer_v3float %out %uint_0 %int_2
+         %28 = OpCompositeExtract %v3float %value 2
+               OpStore %26 %28
+               OpReturn
+               OpFunctionEnd
+       %main = OpFunction %void None %29
+         %31 = OpLabel
+         %34 = OpAccessChain %_ptr_StorageBuffer_mat3v3float %in %uint_0
+         %35 = OpLoad %mat3v3float %34
+         %32 = OpFunctionCall %void %assign_and_preserve_padding_out %35
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/storage/types/mat4x3_f16.wgsl.expected.glsl b/test/tint/buffer/storage/types/mat4x3_f16.wgsl.expected.glsl
index 65e8a13..f81b373 100644
--- a/test/tint/buffer/storage/types/mat4x3_f16.wgsl.expected.glsl
+++ b/test/tint/buffer/storage/types/mat4x3_f16.wgsl.expected.glsl
@@ -9,8 +9,15 @@
   f16mat4x3 inner;
 } tint_symbol_1;
 
+void assign_and_preserve_padding_tint_symbol_1(f16mat4x3 value) {
+  tint_symbol_1.inner[0] = value[0u];
+  tint_symbol_1.inner[1] = value[1u];
+  tint_symbol_1.inner[2] = value[2u];
+  tint_symbol_1.inner[3] = value[3u];
+}
+
 void tint_symbol_2() {
-  tint_symbol_1.inner = tint_symbol.inner;
+  assign_and_preserve_padding_tint_symbol_1(tint_symbol.inner);
 }
 
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/buffer/storage/types/mat4x3_f16.wgsl.expected.msl b/test/tint/buffer/storage/types/mat4x3_f16.wgsl.expected.msl
index 57f08f6..15032a4 100644
--- a/test/tint/buffer/storage/types/mat4x3_f16.wgsl.expected.msl
+++ b/test/tint/buffer/storage/types/mat4x3_f16.wgsl.expected.msl
@@ -1,8 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+void assign_and_preserve_padding(device half4x3* const dest, half4x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+  (*(dest))[3u] = value[3u];
+}
+
 kernel void tint_symbol(device half4x3* tint_symbol_1 [[buffer(0)]], const device half4x3* tint_symbol_2 [[buffer(1)]]) {
-  *(tint_symbol_1) = *(tint_symbol_2);
+  assign_and_preserve_padding(tint_symbol_1, *(tint_symbol_2));
   return;
 }
 
diff --git a/test/tint/buffer/storage/types/mat4x3_f16.wgsl.expected.spvasm b/test/tint/buffer/storage/types/mat4x3_f16.wgsl.expected.spvasm
index 5cd7565..39cc249 100644
--- a/test/tint/buffer/storage/types/mat4x3_f16.wgsl.expected.spvasm
+++ b/test/tint/buffer/storage/types/mat4x3_f16.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 18
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -15,6 +15,8 @@
                OpMemberName %in_block 0 "inner"
                OpName %in "in"
                OpName %out "out"
+               OpName %assign_and_preserve_padding_out "assign_and_preserve_padding_out"
+               OpName %value "value"
                OpName %main "main"
                OpDecorate %in_block Block
                OpMemberDecorate %in_block 0 Offset 0
@@ -33,15 +35,42 @@
          %in = OpVariable %_ptr_StorageBuffer_in_block StorageBuffer
         %out = OpVariable %_ptr_StorageBuffer_in_block StorageBuffer
        %void = OpTypeVoid
-          %8 = OpTypeFunction %void
+          %8 = OpTypeFunction %void %mat4v3half
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
+        %int = OpTypeInt 32 1
+         %16 = OpConstantNull %int
+%_ptr_StorageBuffer_v3half = OpTypePointer StorageBuffer %v3half
+         %19 = OpConstantNull %uint
+      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
+      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
+      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_mat4v3half = OpTypePointer StorageBuffer %mat4v3half
-       %main = OpFunction %void None %8
-         %11 = OpLabel
-         %15 = OpAccessChain %_ptr_StorageBuffer_mat4v3half %out %uint_0
-         %16 = OpAccessChain %_ptr_StorageBuffer_mat4v3half %in %uint_0
-         %17 = OpLoad %mat4v3half %16
-               OpStore %15 %17
+%assign_and_preserve_padding_out = OpFunction %void None %8
+      %value = OpFunctionParameter %mat4v3half
+         %12 = OpLabel
+         %18 = OpAccessChain %_ptr_StorageBuffer_v3half %out %uint_0 %16
+         %20 = OpCompositeExtract %v3half %value 0
+               OpStore %18 %20
+         %22 = OpAccessChain %_ptr_StorageBuffer_v3half %out %uint_0 %int_1
+         %24 = OpCompositeExtract %v3half %value 1
+               OpStore %22 %24
+         %26 = OpAccessChain %_ptr_StorageBuffer_v3half %out %uint_0 %int_2
+         %28 = OpCompositeExtract %v3half %value 2
+               OpStore %26 %28
+         %30 = OpAccessChain %_ptr_StorageBuffer_v3half %out %uint_0 %int_3
+         %32 = OpCompositeExtract %v3half %value 3
+               OpStore %30 %32
+               OpReturn
+               OpFunctionEnd
+       %main = OpFunction %void None %33
+         %35 = OpLabel
+         %38 = OpAccessChain %_ptr_StorageBuffer_mat4v3half %in %uint_0
+         %39 = OpLoad %mat4v3half %38
+         %36 = OpFunctionCall %void %assign_and_preserve_padding_out %39
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/storage/types/mat4x3_f32.wgsl.expected.glsl b/test/tint/buffer/storage/types/mat4x3_f32.wgsl.expected.glsl
index a4a1a8f..63d61f0 100644
--- a/test/tint/buffer/storage/types/mat4x3_f32.wgsl.expected.glsl
+++ b/test/tint/buffer/storage/types/mat4x3_f32.wgsl.expected.glsl
@@ -8,8 +8,15 @@
   mat4x3 inner;
 } tint_symbol_1;
 
+void assign_and_preserve_padding_tint_symbol_1(mat4x3 value) {
+  tint_symbol_1.inner[0] = value[0u];
+  tint_symbol_1.inner[1] = value[1u];
+  tint_symbol_1.inner[2] = value[2u];
+  tint_symbol_1.inner[3] = value[3u];
+}
+
 void tint_symbol_2() {
-  tint_symbol_1.inner = tint_symbol.inner;
+  assign_and_preserve_padding_tint_symbol_1(tint_symbol.inner);
 }
 
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/buffer/storage/types/mat4x3_f32.wgsl.expected.msl b/test/tint/buffer/storage/types/mat4x3_f32.wgsl.expected.msl
index 7465a1a..f5ebf26 100644
--- a/test/tint/buffer/storage/types/mat4x3_f32.wgsl.expected.msl
+++ b/test/tint/buffer/storage/types/mat4x3_f32.wgsl.expected.msl
@@ -1,8 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+void assign_and_preserve_padding(device float4x3* const dest, float4x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+  (*(dest))[3u] = value[3u];
+}
+
 kernel void tint_symbol(device float4x3* tint_symbol_1 [[buffer(0)]], const device float4x3* tint_symbol_2 [[buffer(1)]]) {
-  *(tint_symbol_1) = *(tint_symbol_2);
+  assign_and_preserve_padding(tint_symbol_1, *(tint_symbol_2));
   return;
 }
 
diff --git a/test/tint/buffer/storage/types/mat4x3_f32.wgsl.expected.spvasm b/test/tint/buffer/storage/types/mat4x3_f32.wgsl.expected.spvasm
index 39fafdd..c8f3dd4 100644
--- a/test/tint/buffer/storage/types/mat4x3_f32.wgsl.expected.spvasm
+++ b/test/tint/buffer/storage/types/mat4x3_f32.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 18
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -11,6 +11,8 @@
                OpMemberName %in_block 0 "inner"
                OpName %in "in"
                OpName %out "out"
+               OpName %assign_and_preserve_padding_out "assign_and_preserve_padding_out"
+               OpName %value "value"
                OpName %main "main"
                OpDecorate %in_block Block
                OpMemberDecorate %in_block 0 Offset 0
@@ -29,15 +31,42 @@
          %in = OpVariable %_ptr_StorageBuffer_in_block StorageBuffer
         %out = OpVariable %_ptr_StorageBuffer_in_block StorageBuffer
        %void = OpTypeVoid
-          %8 = OpTypeFunction %void
+          %8 = OpTypeFunction %void %mat4v3float
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
+        %int = OpTypeInt 32 1
+         %16 = OpConstantNull %int
+%_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
+         %19 = OpConstantNull %uint
+      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
+      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
+      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_mat4v3float = OpTypePointer StorageBuffer %mat4v3float
-       %main = OpFunction %void None %8
-         %11 = OpLabel
-         %15 = OpAccessChain %_ptr_StorageBuffer_mat4v3float %out %uint_0
-         %16 = OpAccessChain %_ptr_StorageBuffer_mat4v3float %in %uint_0
-         %17 = OpLoad %mat4v3float %16
-               OpStore %15 %17
+%assign_and_preserve_padding_out = OpFunction %void None %8
+      %value = OpFunctionParameter %mat4v3float
+         %12 = OpLabel
+         %18 = OpAccessChain %_ptr_StorageBuffer_v3float %out %uint_0 %16
+         %20 = OpCompositeExtract %v3float %value 0
+               OpStore %18 %20
+         %22 = OpAccessChain %_ptr_StorageBuffer_v3float %out %uint_0 %int_1
+         %24 = OpCompositeExtract %v3float %value 1
+               OpStore %22 %24
+         %26 = OpAccessChain %_ptr_StorageBuffer_v3float %out %uint_0 %int_2
+         %28 = OpCompositeExtract %v3float %value 2
+               OpStore %26 %28
+         %30 = OpAccessChain %_ptr_StorageBuffer_v3float %out %uint_0 %int_3
+         %32 = OpCompositeExtract %v3float %value 3
+               OpStore %30 %32
+               OpReturn
+               OpFunctionEnd
+       %main = OpFunction %void None %33
+         %35 = OpLabel
+         %38 = OpAccessChain %_ptr_StorageBuffer_mat4v3float %in %uint_0
+         %39 = OpLoad %mat4v3float %38
+         %36 = OpFunctionCall %void %assign_and_preserve_padding_out %39
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_storage.wgsl.expected.glsl
index 48da1c9..b6beec3 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_storage.wgsl.expected.glsl
@@ -14,6 +14,20 @@
   f16mat2x3 inner[4];
 } s;
 
+void assign_and_preserve_padding_1_s_X(uint dest[1], f16mat2x3 value) {
+  s.inner[dest[0]][0] = value[0u];
+  s.inner[dest[0]][1] = value[1u];
+}
+
+void assign_and_preserve_padding_s(f16mat2x3 value[4]) {
+  {
+    for(uint i = 0u; (i < 4u); i = (i + 1u)) {
+      uint tint_symbol[1] = uint[1](i);
+      assign_and_preserve_padding_1_s_X(tint_symbol, value[i]);
+    }
+  }
+}
+
 f16mat2x3 conv_mat2x3_f16(mat2x3_f16 val) {
   return f16mat2x3(val.col0, val.col1);
 }
@@ -29,8 +43,9 @@
 }
 
 void f() {
-  s.inner = conv_arr4_mat2x3_f16(u.inner);
-  s.inner[1] = conv_mat2x3_f16(u.inner[2u]);
+  assign_and_preserve_padding_s(conv_arr4_mat2x3_f16(u.inner));
+  uint tint_symbol_1[1] = uint[1](1u);
+  assign_and_preserve_padding_1_s_X(tint_symbol_1, conv_mat2x3_f16(u.inner[2u]));
   s.inner[1][0] = u.inner[0u].col1.zxy;
   s.inner[1][0].x = u.inner[0u].col1[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_storage.wgsl.expected.msl
index edcc1d9..c24c518 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_storage.wgsl.expected.msl
@@ -14,9 +14,20 @@
     T elements[N];
 };
 
+void assign_and_preserve_padding_1(device half2x3* const dest, half2x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+}
+
+void assign_and_preserve_padding(device tint_array<half2x3, 4>* const dest, tint_array<half2x3, 4> value) {
+  for(uint i = 0u; (i < 4u); i = (i + 1u)) {
+    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+  }
+}
+
 kernel void f(device tint_array<half2x3, 4>* tint_symbol [[buffer(1)]], const constant tint_array<half2x3, 4>* tint_symbol_1 [[buffer(0)]]) {
-  *(tint_symbol) = *(tint_symbol_1);
-  (*(tint_symbol))[1] = (*(tint_symbol_1))[2];
+  assign_and_preserve_padding(tint_symbol, *(tint_symbol_1));
+  assign_and_preserve_padding_1(&((*(tint_symbol))[1]), (*(tint_symbol_1))[2]);
   (*(tint_symbol))[1][0] = half3((*(tint_symbol_1))[0][1]).zxy;
   (*(tint_symbol))[1][0][0] = (*(tint_symbol_1))[0][1][0];
   return;
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_storage.wgsl.expected.spvasm
index 8d6eba2..edd6568 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 89
+; Bound: 123
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -20,13 +20,20 @@
                OpName %u_block "u_block"
                OpMemberName %u_block 0 "inner"
                OpName %s "s"
+               OpName %assign_and_preserve_padding_1_s_X "assign_and_preserve_padding_1_s_X"
+               OpName %dest "dest"
+               OpName %value "value"
+               OpName %assign_and_preserve_padding_s "assign_and_preserve_padding_s"
+               OpName %value_0 "value"
+               OpName %i "i"
+               OpName %var_for_index "var_for_index"
                OpName %conv_mat2x3_f16 "conv_mat2x3_f16"
                OpName %val "val"
                OpName %conv_arr4_mat2x3_f16 "conv_arr4_mat2x3_f16"
                OpName %val_0 "val"
                OpName %arr "arr"
-               OpName %i "i"
-               OpName %var_for_index "var_for_index"
+               OpName %i_0 "i"
+               OpName %var_for_index_1 "var_for_index_1"
                OpName %f "f"
                OpDecorate %u_block_std140 Block
                OpMemberDecorate %u_block_std140 0 Offset 0
@@ -43,6 +50,7 @@
                OpDecorate %_arr_mat2v3half_uint_4 ArrayStride 16
                OpDecorate %s DescriptorSet 0
                OpDecorate %s Binding 1
+               OpDecorate %_arr_uint_uint_1 ArrayStride 4
        %half = OpTypeFloat 16
      %v3half = OpTypeVector %half 3
  %mat2x3_f16 = OpTypeStruct %v3half %v3half
@@ -57,98 +65,147 @@
     %u_block = OpTypeStruct %_arr_mat2v3half_uint_4
 %_ptr_StorageBuffer_u_block = OpTypePointer StorageBuffer %u_block
           %s = OpVariable %_ptr_StorageBuffer_u_block StorageBuffer
-         %15 = OpTypeFunction %mat2v3half %mat2x3_f16
-         %22 = OpTypeFunction %_arr_mat2v3half_uint_4 %_arr_mat2x3_f16_uint_4
-%_ptr_Function__arr_mat2v3half_uint_4 = OpTypePointer Function %_arr_mat2v3half_uint_4
-         %28 = OpConstantNull %_arr_mat2v3half_uint_4
-%_ptr_Function_uint = OpTypePointer Function %uint
-         %31 = OpConstantNull %uint
-       %bool = OpTypeBool
-%_ptr_Function__arr_mat2x3_f16_uint_4 = OpTypePointer Function %_arr_mat2x3_f16_uint_4
-         %44 = OpConstantNull %_arr_mat2x3_f16_uint_4
-%_ptr_Function_mat2v3half = OpTypePointer Function %mat2v3half
-%_ptr_Function_mat2x3_f16 = OpTypePointer Function %mat2x3_f16
-     %uint_1 = OpConstant %uint 1
        %void = OpTypeVoid
-         %57 = OpTypeFunction %void
+     %uint_1 = OpConstant %uint 1
+%_arr_uint_uint_1 = OpTypeArray %uint %uint_1
+         %15 = OpTypeFunction %void %_arr_uint_uint_1 %mat2v3half
      %uint_0 = OpConstant %uint 0
-%_ptr_StorageBuffer__arr_mat2v3half_uint_4 = OpTypePointer StorageBuffer %_arr_mat2v3half_uint_4
-%_ptr_Uniform__arr_mat2x3_f16_uint_4 = OpTypePointer Uniform %_arr_mat2x3_f16_uint_4
         %int = OpTypeInt 32 1
+         %25 = OpConstantNull %int
+%_ptr_StorageBuffer_v3half = OpTypePointer StorageBuffer %v3half
+         %29 = OpConstantNull %uint
       %int_1 = OpConstant %int 1
-%_ptr_StorageBuffer_mat2v3half = OpTypePointer StorageBuffer %mat2v3half
+         %35 = OpTypeFunction %void %_arr_mat2v3half_uint_4
+%_ptr_Function_uint = OpTypePointer Function %uint
+       %bool = OpTypeBool
+%_ptr_Function__arr_mat2v3half_uint_4 = OpTypePointer Function %_arr_mat2v3half_uint_4
+         %53 = OpConstantNull %_arr_mat2v3half_uint_4
+%_ptr_Function_mat2v3half = OpTypePointer Function %mat2v3half
+         %63 = OpTypeFunction %mat2v3half %mat2x3_f16
+         %70 = OpTypeFunction %_arr_mat2v3half_uint_4 %_arr_mat2x3_f16_uint_4
+%_ptr_Function__arr_mat2x3_f16_uint_4 = OpTypePointer Function %_arr_mat2x3_f16_uint_4
+         %87 = OpConstantNull %_arr_mat2x3_f16_uint_4
+%_ptr_Function_mat2x3_f16 = OpTypePointer Function %mat2x3_f16
+         %98 = OpTypeFunction %void
+%_ptr_Uniform__arr_mat2x3_f16_uint_4 = OpTypePointer Uniform %_arr_mat2x3_f16_uint_4
+        %107 = OpConstantComposite %_arr_uint_uint_1 %uint_1
      %uint_2 = OpConstant %uint 2
 %_ptr_Uniform_mat2x3_f16 = OpTypePointer Uniform %mat2x3_f16
-         %77 = OpConstantNull %int
-%_ptr_StorageBuffer_v3half = OpTypePointer StorageBuffer %v3half
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
 %_ptr_Uniform_half = OpTypePointer Uniform %half
-%conv_mat2x3_f16 = OpFunction %mat2v3half None %15
-        %val = OpFunctionParameter %mat2x3_f16
-         %18 = OpLabel
-         %19 = OpCompositeExtract %v3half %val 0
-         %20 = OpCompositeExtract %v3half %val 1
-         %21 = OpCompositeConstruct %mat2v3half %19 %20
-               OpReturnValue %21
+%assign_and_preserve_padding_1_s_X = OpFunction %void None %15
+       %dest = OpFunctionParameter %_arr_uint_uint_1
+      %value = OpFunctionParameter %mat2v3half
+         %22 = OpLabel
+         %26 = OpCompositeExtract %uint %dest 0
+         %28 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %26 %25
+         %30 = OpCompositeExtract %v3half %value 0
+               OpStore %28 %30
+         %31 = OpCompositeExtract %uint %dest 0
+         %33 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %31 %int_1
+         %34 = OpCompositeExtract %v3half %value 1
+               OpStore %33 %34
+               OpReturn
                OpFunctionEnd
-%conv_arr4_mat2x3_f16 = OpFunction %_arr_mat2v3half_uint_4 None %22
-      %val_0 = OpFunctionParameter %_arr_mat2x3_f16_uint_4
-         %25 = OpLabel
-        %arr = OpVariable %_ptr_Function__arr_mat2v3half_uint_4 Function %28
-          %i = OpVariable %_ptr_Function_uint Function %31
-%var_for_index = OpVariable %_ptr_Function__arr_mat2x3_f16_uint_4 Function %44
-               OpBranch %32
-         %32 = OpLabel
-               OpLoopMerge %33 %34 None
-               OpBranch %35
-         %35 = OpLabel
-         %37 = OpLoad %uint %i
-         %38 = OpULessThan %bool %37 %uint_4
-         %36 = OpLogicalNot %bool %38
-               OpSelectionMerge %40 None
-               OpBranchConditional %36 %41 %40
+%assign_and_preserve_padding_s = OpFunction %void None %35
+    %value_0 = OpFunctionParameter %_arr_mat2v3half_uint_4
+         %38 = OpLabel
+          %i = OpVariable %_ptr_Function_uint Function %29
+%var_for_index = OpVariable %_ptr_Function__arr_mat2v3half_uint_4 Function %53
+               OpStore %i %29
+               OpBranch %41
          %41 = OpLabel
-               OpBranch %33
-         %40 = OpLabel
-               OpStore %var_for_index %val_0
-         %45 = OpLoad %uint %i
-         %47 = OpAccessChain %_ptr_Function_mat2v3half %arr %45
-         %49 = OpLoad %uint %i
-         %51 = OpAccessChain %_ptr_Function_mat2x3_f16 %var_for_index %49
-         %52 = OpLoad %mat2x3_f16 %51
-         %48 = OpFunctionCall %mat2v3half %conv_mat2x3_f16 %52
-               OpStore %47 %48
-               OpBranch %34
-         %34 = OpLabel
-         %53 = OpLoad %uint %i
-         %55 = OpIAdd %uint %53 %uint_1
-               OpStore %i %55
-               OpBranch %32
-         %33 = OpLabel
-         %56 = OpLoad %_arr_mat2v3half_uint_4 %arr
-               OpReturnValue %56
+               OpLoopMerge %42 %43 None
+               OpBranch %44
+         %44 = OpLabel
+         %46 = OpLoad %uint %i
+         %47 = OpULessThan %bool %46 %uint_4
+         %45 = OpLogicalNot %bool %47
+               OpSelectionMerge %49 None
+               OpBranchConditional %45 %50 %49
+         %50 = OpLabel
+               OpBranch %42
+         %49 = OpLabel
+               OpStore %var_for_index %value_0
+         %55 = OpLoad %uint %i
+         %56 = OpCompositeConstruct %_arr_uint_uint_1 %55
+         %57 = OpLoad %uint %i
+         %59 = OpAccessChain %_ptr_Function_mat2v3half %var_for_index %57
+         %60 = OpLoad %mat2v3half %59
+         %54 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %56 %60
+               OpBranch %43
+         %43 = OpLabel
+         %61 = OpLoad %uint %i
+         %62 = OpIAdd %uint %61 %uint_1
+               OpStore %i %62
+               OpBranch %41
+         %42 = OpLabel
+               OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %57
-         %60 = OpLabel
-         %63 = OpAccessChain %_ptr_StorageBuffer__arr_mat2v3half_uint_4 %s %uint_0
-         %66 = OpAccessChain %_ptr_Uniform__arr_mat2x3_f16_uint_4 %u %uint_0
-         %67 = OpLoad %_arr_mat2x3_f16_uint_4 %66
-         %64 = OpFunctionCall %_arr_mat2v3half_uint_4 %conv_arr4_mat2x3_f16 %67
-               OpStore %63 %64
-         %71 = OpAccessChain %_ptr_StorageBuffer_mat2v3half %s %uint_0 %int_1
-         %75 = OpAccessChain %_ptr_Uniform_mat2x3_f16 %u %uint_0 %uint_2
-         %76 = OpLoad %mat2x3_f16 %75
-         %72 = OpFunctionCall %mat2v3half %conv_mat2x3_f16 %76
-               OpStore %71 %72
-         %79 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %int_1 %77
-         %81 = OpAccessChain %_ptr_Uniform_v3half %u %uint_0 %31 %uint_1
-         %82 = OpLoad %v3half %81
-         %83 = OpVectorShuffle %v3half %82 %82 2 0 1
-               OpStore %79 %83
-         %85 = OpAccessChain %_ptr_StorageBuffer_half %s %uint_0 %int_1 %77 %uint_0
-         %87 = OpAccessChain %_ptr_Uniform_half %u %uint_0 %31 %uint_1 %31
-         %88 = OpLoad %half %87
-               OpStore %85 %88
+%conv_mat2x3_f16 = OpFunction %mat2v3half None %63
+        %val = OpFunctionParameter %mat2x3_f16
+         %66 = OpLabel
+         %67 = OpCompositeExtract %v3half %val 0
+         %68 = OpCompositeExtract %v3half %val 1
+         %69 = OpCompositeConstruct %mat2v3half %67 %68
+               OpReturnValue %69
+               OpFunctionEnd
+%conv_arr4_mat2x3_f16 = OpFunction %_arr_mat2v3half_uint_4 None %70
+      %val_0 = OpFunctionParameter %_arr_mat2x3_f16_uint_4
+         %73 = OpLabel
+        %arr = OpVariable %_ptr_Function__arr_mat2v3half_uint_4 Function %53
+        %i_0 = OpVariable %_ptr_Function_uint Function %29
+%var_for_index_1 = OpVariable %_ptr_Function__arr_mat2x3_f16_uint_4 Function %87
+               OpBranch %76
+         %76 = OpLabel
+               OpLoopMerge %77 %78 None
+               OpBranch %79
+         %79 = OpLabel
+         %81 = OpLoad %uint %i_0
+         %82 = OpULessThan %bool %81 %uint_4
+         %80 = OpLogicalNot %bool %82
+               OpSelectionMerge %83 None
+               OpBranchConditional %80 %84 %83
+         %84 = OpLabel
+               OpBranch %77
+         %83 = OpLabel
+               OpStore %var_for_index_1 %val_0
+         %88 = OpLoad %uint %i_0
+         %89 = OpAccessChain %_ptr_Function_mat2v3half %arr %88
+         %91 = OpLoad %uint %i_0
+         %93 = OpAccessChain %_ptr_Function_mat2x3_f16 %var_for_index_1 %91
+         %94 = OpLoad %mat2x3_f16 %93
+         %90 = OpFunctionCall %mat2v3half %conv_mat2x3_f16 %94
+               OpStore %89 %90
+               OpBranch %78
+         %78 = OpLabel
+         %95 = OpLoad %uint %i_0
+         %96 = OpIAdd %uint %95 %uint_1
+               OpStore %i_0 %96
+               OpBranch %76
+         %77 = OpLabel
+         %97 = OpLoad %_arr_mat2v3half_uint_4 %arr
+               OpReturnValue %97
+               OpFunctionEnd
+          %f = OpFunction %void None %98
+        %100 = OpLabel
+        %104 = OpAccessChain %_ptr_Uniform__arr_mat2x3_f16_uint_4 %u %uint_0
+        %105 = OpLoad %_arr_mat2x3_f16_uint_4 %104
+        %102 = OpFunctionCall %_arr_mat2v3half_uint_4 %conv_arr4_mat2x3_f16 %105
+        %101 = OpFunctionCall %void %assign_and_preserve_padding_s %102
+        %111 = OpAccessChain %_ptr_Uniform_mat2x3_f16 %u %uint_0 %uint_2
+        %112 = OpLoad %mat2x3_f16 %111
+        %108 = OpFunctionCall %mat2v3half %conv_mat2x3_f16 %112
+        %106 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %107 %108
+        %113 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %int_1 %25
+        %115 = OpAccessChain %_ptr_Uniform_v3half %u %uint_0 %29 %uint_1
+        %116 = OpLoad %v3half %115
+        %117 = OpVectorShuffle %v3half %116 %116 2 0 1
+               OpStore %113 %117
+        %119 = OpAccessChain %_ptr_StorageBuffer_half %s %uint_0 %int_1 %25 %uint_0
+        %121 = OpAccessChain %_ptr_Uniform_half %u %uint_0 %29 %uint_1 %29
+        %122 = OpLoad %half %121
+               OpStore %119 %122
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_storage.wgsl.expected.glsl
index 08b531f..d432b3c 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_storage.wgsl.expected.glsl
@@ -8,9 +8,24 @@
   mat2x3 inner[4];
 } s;
 
+void assign_and_preserve_padding_1_s_X(uint dest[1], mat2x3 value) {
+  s.inner[dest[0]][0] = value[0u];
+  s.inner[dest[0]][1] = value[1u];
+}
+
+void assign_and_preserve_padding_s(mat2x3 value[4]) {
+  {
+    for(uint i = 0u; (i < 4u); i = (i + 1u)) {
+      uint tint_symbol[1] = uint[1](i);
+      assign_and_preserve_padding_1_s_X(tint_symbol, value[i]);
+    }
+  }
+}
+
 void f() {
-  s.inner = u.inner;
-  s.inner[1] = u.inner[2];
+  assign_and_preserve_padding_s(u.inner);
+  uint tint_symbol_1[1] = uint[1](1u);
+  assign_and_preserve_padding_1_s_X(tint_symbol_1, u.inner[2]);
   s.inner[1][0] = u.inner[0][1].zxy;
   s.inner[1][0].x = u.inner[0][1].x;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_storage.wgsl.expected.msl
index 42f3b1d..09cbcc4 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_storage.wgsl.expected.msl
@@ -14,9 +14,20 @@
     T elements[N];
 };
 
+void assign_and_preserve_padding_1(device float2x3* const dest, float2x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+}
+
+void assign_and_preserve_padding(device tint_array<float2x3, 4>* const dest, tint_array<float2x3, 4> value) {
+  for(uint i = 0u; (i < 4u); i = (i + 1u)) {
+    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+  }
+}
+
 kernel void f(device tint_array<float2x3, 4>* tint_symbol [[buffer(1)]], const constant tint_array<float2x3, 4>* tint_symbol_1 [[buffer(0)]]) {
-  *(tint_symbol) = *(tint_symbol_1);
-  (*(tint_symbol))[1] = (*(tint_symbol_1))[2];
+  assign_and_preserve_padding(tint_symbol, *(tint_symbol_1));
+  assign_and_preserve_padding_1(&((*(tint_symbol))[1]), (*(tint_symbol_1))[2]);
   (*(tint_symbol))[1][0] = float3((*(tint_symbol_1))[0][1]).zxy;
   (*(tint_symbol))[1][0][0] = (*(tint_symbol_1))[0][1][0];
   return;
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_storage.wgsl.expected.spvasm
index e7e86aa..1db9747 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 42
+; Bound: 83
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -11,6 +11,13 @@
                OpMemberName %u_block 0 "inner"
                OpName %u "u"
                OpName %s "s"
+               OpName %assign_and_preserve_padding_1_s_X "assign_and_preserve_padding_1_s_X"
+               OpName %dest "dest"
+               OpName %value "value"
+               OpName %assign_and_preserve_padding_s "assign_and_preserve_padding_s"
+               OpName %value_0 "value"
+               OpName %i "i"
+               OpName %var_for_index "var_for_index"
                OpName %f "f"
                OpDecorate %u_block Block
                OpMemberDecorate %u_block 0 Offset 0
@@ -22,6 +29,7 @@
                OpDecorate %u Binding 0
                OpDecorate %s DescriptorSet 0
                OpDecorate %s Binding 1
+               OpDecorate %_arr_uint_uint_1 ArrayStride 4
       %float = OpTypeFloat 32
     %v3float = OpTypeVector %float 3
 %mat2v3float = OpTypeMatrix %v3float 2
@@ -34,38 +42,94 @@
 %_ptr_StorageBuffer_u_block = OpTypePointer StorageBuffer %u_block
           %s = OpVariable %_ptr_StorageBuffer_u_block StorageBuffer
        %void = OpTypeVoid
-         %12 = OpTypeFunction %void
+     %uint_1 = OpConstant %uint 1
+%_arr_uint_uint_1 = OpTypeArray %uint %uint_1
+         %12 = OpTypeFunction %void %_arr_uint_uint_1 %mat2v3float
      %uint_0 = OpConstant %uint 0
-%_ptr_StorageBuffer__arr_mat2v3float_uint_4 = OpTypePointer StorageBuffer %_arr_mat2v3float_uint_4
-%_ptr_Uniform__arr_mat2v3float_uint_4 = OpTypePointer Uniform %_arr_mat2v3float_uint_4
         %int = OpTypeInt 32 1
+         %22 = OpConstantNull %int
+%_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
+         %26 = OpConstantNull %uint
       %int_1 = OpConstant %int 1
-%_ptr_StorageBuffer_mat2v3float = OpTypePointer StorageBuffer %mat2v3float
+         %32 = OpTypeFunction %void %_arr_mat2v3float_uint_4
+%_ptr_Function_uint = OpTypePointer Function %uint
+       %bool = OpTypeBool
+%_ptr_Function__arr_mat2v3float_uint_4 = OpTypePointer Function %_arr_mat2v3float_uint_4
+         %50 = OpConstantNull %_arr_mat2v3float_uint_4
+%_ptr_Function_mat2v3float = OpTypePointer Function %mat2v3float
+         %60 = OpTypeFunction %void
+%_ptr_Uniform__arr_mat2v3float_uint_4 = OpTypePointer Uniform %_arr_mat2v3float_uint_4
+         %68 = OpConstantComposite %_arr_uint_uint_1 %uint_1
       %int_2 = OpConstant %int 2
 %_ptr_Uniform_mat2v3float = OpTypePointer Uniform %mat2v3float
-         %30 = OpConstantNull %int
-%_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
 %_ptr_Uniform_float = OpTypePointer Uniform %float
-          %f = OpFunction %void None %12
-         %15 = OpLabel
-         %18 = OpAccessChain %_ptr_StorageBuffer__arr_mat2v3float_uint_4 %s %uint_0
-         %20 = OpAccessChain %_ptr_Uniform__arr_mat2v3float_uint_4 %u %uint_0
-         %21 = OpLoad %_arr_mat2v3float_uint_4 %20
-               OpStore %18 %21
-         %25 = OpAccessChain %_ptr_StorageBuffer_mat2v3float %s %uint_0 %int_1
-         %28 = OpAccessChain %_ptr_Uniform_mat2v3float %u %uint_0 %int_2
-         %29 = OpLoad %mat2v3float %28
-               OpStore %25 %29
-         %32 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %int_1 %30
-         %34 = OpAccessChain %_ptr_Uniform_v3float %u %uint_0 %30 %int_1
-         %35 = OpLoad %v3float %34
-         %36 = OpVectorShuffle %v3float %35 %35 2 0 1
-               OpStore %32 %36
-         %38 = OpAccessChain %_ptr_StorageBuffer_float %s %uint_0 %int_1 %30 %uint_0
-         %40 = OpAccessChain %_ptr_Uniform_float %u %uint_0 %30 %int_1 %uint_0
-         %41 = OpLoad %float %40
-               OpStore %38 %41
+%assign_and_preserve_padding_1_s_X = OpFunction %void None %12
+       %dest = OpFunctionParameter %_arr_uint_uint_1
+      %value = OpFunctionParameter %mat2v3float
+         %19 = OpLabel
+         %23 = OpCompositeExtract %uint %dest 0
+         %25 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %23 %22
+         %27 = OpCompositeExtract %v3float %value 0
+               OpStore %25 %27
+         %28 = OpCompositeExtract %uint %dest 0
+         %30 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %28 %int_1
+         %31 = OpCompositeExtract %v3float %value 1
+               OpStore %30 %31
+               OpReturn
+               OpFunctionEnd
+%assign_and_preserve_padding_s = OpFunction %void None %32
+    %value_0 = OpFunctionParameter %_arr_mat2v3float_uint_4
+         %35 = OpLabel
+          %i = OpVariable %_ptr_Function_uint Function %26
+%var_for_index = OpVariable %_ptr_Function__arr_mat2v3float_uint_4 Function %50
+               OpStore %i %26
+               OpBranch %38
+         %38 = OpLabel
+               OpLoopMerge %39 %40 None
+               OpBranch %41
+         %41 = OpLabel
+         %43 = OpLoad %uint %i
+         %44 = OpULessThan %bool %43 %uint_4
+         %42 = OpLogicalNot %bool %44
+               OpSelectionMerge %46 None
+               OpBranchConditional %42 %47 %46
+         %47 = OpLabel
+               OpBranch %39
+         %46 = OpLabel
+               OpStore %var_for_index %value_0
+         %52 = OpLoad %uint %i
+         %53 = OpCompositeConstruct %_arr_uint_uint_1 %52
+         %54 = OpLoad %uint %i
+         %56 = OpAccessChain %_ptr_Function_mat2v3float %var_for_index %54
+         %57 = OpLoad %mat2v3float %56
+         %51 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %53 %57
+               OpBranch %40
+         %40 = OpLabel
+         %58 = OpLoad %uint %i
+         %59 = OpIAdd %uint %58 %uint_1
+               OpStore %i %59
+               OpBranch %38
+         %39 = OpLabel
+               OpReturn
+               OpFunctionEnd
+          %f = OpFunction %void None %60
+         %62 = OpLabel
+         %65 = OpAccessChain %_ptr_Uniform__arr_mat2v3float_uint_4 %u %uint_0
+         %66 = OpLoad %_arr_mat2v3float_uint_4 %65
+         %63 = OpFunctionCall %void %assign_and_preserve_padding_s %66
+         %71 = OpAccessChain %_ptr_Uniform_mat2v3float %u %uint_0 %int_2
+         %72 = OpLoad %mat2v3float %71
+         %67 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %68 %72
+         %73 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %int_1 %22
+         %75 = OpAccessChain %_ptr_Uniform_v3float %u %uint_0 %22 %int_1
+         %76 = OpLoad %v3float %75
+         %77 = OpVectorShuffle %v3float %76 %76 2 0 1
+               OpStore %73 %77
+         %79 = OpAccessChain %_ptr_StorageBuffer_float %s %uint_0 %int_1 %22 %uint_0
+         %81 = OpAccessChain %_ptr_Uniform_float %u %uint_0 %22 %int_1 %uint_0
+         %82 = OpLoad %float %81
+               OpStore %79 %82
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_storage.wgsl.expected.glsl
index 9105811..f8fa240 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_storage.wgsl.expected.glsl
@@ -8,9 +8,25 @@
   mat3 inner[4];
 } s;
 
+void assign_and_preserve_padding_1_s_X(uint dest[1], mat3 value) {
+  s.inner[dest[0]][0] = value[0u];
+  s.inner[dest[0]][1] = value[1u];
+  s.inner[dest[0]][2] = value[2u];
+}
+
+void assign_and_preserve_padding_s(mat3 value[4]) {
+  {
+    for(uint i = 0u; (i < 4u); i = (i + 1u)) {
+      uint tint_symbol[1] = uint[1](i);
+      assign_and_preserve_padding_1_s_X(tint_symbol, value[i]);
+    }
+  }
+}
+
 void f() {
-  s.inner = u.inner;
-  s.inner[1] = u.inner[2];
+  assign_and_preserve_padding_s(u.inner);
+  uint tint_symbol_1[1] = uint[1](1u);
+  assign_and_preserve_padding_1_s_X(tint_symbol_1, u.inner[2]);
   s.inner[1][0] = u.inner[0][1].zxy;
   s.inner[1][0].x = u.inner[0][1].x;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_storage.wgsl.expected.msl
index 048579a..39aa2fc 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_storage.wgsl.expected.msl
@@ -14,9 +14,21 @@
     T elements[N];
 };
 
+void assign_and_preserve_padding_1(device float3x3* const dest, float3x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+}
+
+void assign_and_preserve_padding(device tint_array<float3x3, 4>* const dest, tint_array<float3x3, 4> value) {
+  for(uint i = 0u; (i < 4u); i = (i + 1u)) {
+    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+  }
+}
+
 kernel void f(device tint_array<float3x3, 4>* tint_symbol [[buffer(1)]], const constant tint_array<float3x3, 4>* tint_symbol_1 [[buffer(0)]]) {
-  *(tint_symbol) = *(tint_symbol_1);
-  (*(tint_symbol))[1] = (*(tint_symbol_1))[2];
+  assign_and_preserve_padding(tint_symbol, *(tint_symbol_1));
+  assign_and_preserve_padding_1(&((*(tint_symbol))[1]), (*(tint_symbol_1))[2]);
   (*(tint_symbol))[1][0] = float3((*(tint_symbol_1))[0][1]).zxy;
   (*(tint_symbol))[1][0][0] = (*(tint_symbol_1))[0][1][0];
   return;
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_storage.wgsl.expected.spvasm
index 2dd00c0..5d5bc7e 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 42
+; Bound: 87
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -11,6 +11,13 @@
                OpMemberName %u_block 0 "inner"
                OpName %u "u"
                OpName %s "s"
+               OpName %assign_and_preserve_padding_1_s_X "assign_and_preserve_padding_1_s_X"
+               OpName %dest "dest"
+               OpName %value "value"
+               OpName %assign_and_preserve_padding_s "assign_and_preserve_padding_s"
+               OpName %value_0 "value"
+               OpName %i "i"
+               OpName %var_for_index "var_for_index"
                OpName %f "f"
                OpDecorate %u_block Block
                OpMemberDecorate %u_block 0 Offset 0
@@ -22,6 +29,7 @@
                OpDecorate %u Binding 0
                OpDecorate %s DescriptorSet 0
                OpDecorate %s Binding 1
+               OpDecorate %_arr_uint_uint_1 ArrayStride 4
       %float = OpTypeFloat 32
     %v3float = OpTypeVector %float 3
 %mat3v3float = OpTypeMatrix %v3float 3
@@ -34,38 +42,99 @@
 %_ptr_StorageBuffer_u_block = OpTypePointer StorageBuffer %u_block
           %s = OpVariable %_ptr_StorageBuffer_u_block StorageBuffer
        %void = OpTypeVoid
-         %12 = OpTypeFunction %void
+     %uint_1 = OpConstant %uint 1
+%_arr_uint_uint_1 = OpTypeArray %uint %uint_1
+         %12 = OpTypeFunction %void %_arr_uint_uint_1 %mat3v3float
      %uint_0 = OpConstant %uint 0
-%_ptr_StorageBuffer__arr_mat3v3float_uint_4 = OpTypePointer StorageBuffer %_arr_mat3v3float_uint_4
-%_ptr_Uniform__arr_mat3v3float_uint_4 = OpTypePointer Uniform %_arr_mat3v3float_uint_4
         %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-%_ptr_StorageBuffer_mat3v3float = OpTypePointer StorageBuffer %mat3v3float
-      %int_2 = OpConstant %int 2
-%_ptr_Uniform_mat3v3float = OpTypePointer Uniform %mat3v3float
-         %30 = OpConstantNull %int
+         %22 = OpConstantNull %int
 %_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
+         %26 = OpConstantNull %uint
+      %int_1 = OpConstant %int 1
+      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
+         %37 = OpTypeFunction %void %_arr_mat3v3float_uint_4
+%_ptr_Function_uint = OpTypePointer Function %uint
+       %bool = OpTypeBool
+%_ptr_Function__arr_mat3v3float_uint_4 = OpTypePointer Function %_arr_mat3v3float_uint_4
+         %55 = OpConstantNull %_arr_mat3v3float_uint_4
+%_ptr_Function_mat3v3float = OpTypePointer Function %mat3v3float
+         %65 = OpTypeFunction %void
+%_ptr_Uniform__arr_mat3v3float_uint_4 = OpTypePointer Uniform %_arr_mat3v3float_uint_4
+         %73 = OpConstantComposite %_arr_uint_uint_1 %uint_1
+%_ptr_Uniform_mat3v3float = OpTypePointer Uniform %mat3v3float
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
 %_ptr_Uniform_float = OpTypePointer Uniform %float
-          %f = OpFunction %void None %12
-         %15 = OpLabel
-         %18 = OpAccessChain %_ptr_StorageBuffer__arr_mat3v3float_uint_4 %s %uint_0
-         %20 = OpAccessChain %_ptr_Uniform__arr_mat3v3float_uint_4 %u %uint_0
-         %21 = OpLoad %_arr_mat3v3float_uint_4 %20
-               OpStore %18 %21
-         %25 = OpAccessChain %_ptr_StorageBuffer_mat3v3float %s %uint_0 %int_1
-         %28 = OpAccessChain %_ptr_Uniform_mat3v3float %u %uint_0 %int_2
-         %29 = OpLoad %mat3v3float %28
-               OpStore %25 %29
-         %32 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %int_1 %30
-         %34 = OpAccessChain %_ptr_Uniform_v3float %u %uint_0 %30 %int_1
-         %35 = OpLoad %v3float %34
-         %36 = OpVectorShuffle %v3float %35 %35 2 0 1
-               OpStore %32 %36
-         %38 = OpAccessChain %_ptr_StorageBuffer_float %s %uint_0 %int_1 %30 %uint_0
-         %40 = OpAccessChain %_ptr_Uniform_float %u %uint_0 %30 %int_1 %uint_0
-         %41 = OpLoad %float %40
-               OpStore %38 %41
+%assign_and_preserve_padding_1_s_X = OpFunction %void None %12
+       %dest = OpFunctionParameter %_arr_uint_uint_1
+      %value = OpFunctionParameter %mat3v3float
+         %19 = OpLabel
+         %23 = OpCompositeExtract %uint %dest 0
+         %25 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %23 %22
+         %27 = OpCompositeExtract %v3float %value 0
+               OpStore %25 %27
+         %28 = OpCompositeExtract %uint %dest 0
+         %30 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %28 %int_1
+         %31 = OpCompositeExtract %v3float %value 1
+               OpStore %30 %31
+         %32 = OpCompositeExtract %uint %dest 0
+         %34 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %32 %int_2
+         %36 = OpCompositeExtract %v3float %value 2
+               OpStore %34 %36
+               OpReturn
+               OpFunctionEnd
+%assign_and_preserve_padding_s = OpFunction %void None %37
+    %value_0 = OpFunctionParameter %_arr_mat3v3float_uint_4
+         %40 = OpLabel
+          %i = OpVariable %_ptr_Function_uint Function %26
+%var_for_index = OpVariable %_ptr_Function__arr_mat3v3float_uint_4 Function %55
+               OpStore %i %26
+               OpBranch %43
+         %43 = OpLabel
+               OpLoopMerge %44 %45 None
+               OpBranch %46
+         %46 = OpLabel
+         %48 = OpLoad %uint %i
+         %49 = OpULessThan %bool %48 %uint_4
+         %47 = OpLogicalNot %bool %49
+               OpSelectionMerge %51 None
+               OpBranchConditional %47 %52 %51
+         %52 = OpLabel
+               OpBranch %44
+         %51 = OpLabel
+               OpStore %var_for_index %value_0
+         %57 = OpLoad %uint %i
+         %58 = OpCompositeConstruct %_arr_uint_uint_1 %57
+         %59 = OpLoad %uint %i
+         %61 = OpAccessChain %_ptr_Function_mat3v3float %var_for_index %59
+         %62 = OpLoad %mat3v3float %61
+         %56 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %58 %62
+               OpBranch %45
+         %45 = OpLabel
+         %63 = OpLoad %uint %i
+         %64 = OpIAdd %uint %63 %uint_1
+               OpStore %i %64
+               OpBranch %43
+         %44 = OpLabel
+               OpReturn
+               OpFunctionEnd
+          %f = OpFunction %void None %65
+         %67 = OpLabel
+         %70 = OpAccessChain %_ptr_Uniform__arr_mat3v3float_uint_4 %u %uint_0
+         %71 = OpLoad %_arr_mat3v3float_uint_4 %70
+         %68 = OpFunctionCall %void %assign_and_preserve_padding_s %71
+         %75 = OpAccessChain %_ptr_Uniform_mat3v3float %u %uint_0 %int_2
+         %76 = OpLoad %mat3v3float %75
+         %72 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %73 %76
+         %77 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %int_1 %22
+         %79 = OpAccessChain %_ptr_Uniform_v3float %u %uint_0 %22 %int_1
+         %80 = OpLoad %v3float %79
+         %81 = OpVectorShuffle %v3float %80 %80 2 0 1
+               OpStore %77 %81
+         %83 = OpAccessChain %_ptr_StorageBuffer_float %s %uint_0 %int_1 %22 %uint_0
+         %85 = OpAccessChain %_ptr_Uniform_float %u %uint_0 %22 %int_1 %uint_0
+         %86 = OpLoad %float %85
+               OpStore %83 %86
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_storage.wgsl.expected.glsl
index 2bf3e2f..8a25d93 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_storage.wgsl.expected.glsl
@@ -16,6 +16,22 @@
   f16mat4x3 inner[4];
 } s;
 
+void assign_and_preserve_padding_1_s_X(uint dest[1], f16mat4x3 value) {
+  s.inner[dest[0]][0] = value[0u];
+  s.inner[dest[0]][1] = value[1u];
+  s.inner[dest[0]][2] = value[2u];
+  s.inner[dest[0]][3] = value[3u];
+}
+
+void assign_and_preserve_padding_s(f16mat4x3 value[4]) {
+  {
+    for(uint i = 0u; (i < 4u); i = (i + 1u)) {
+      uint tint_symbol[1] = uint[1](i);
+      assign_and_preserve_padding_1_s_X(tint_symbol, value[i]);
+    }
+  }
+}
+
 f16mat4x3 conv_mat4x3_f16(mat4x3_f16 val) {
   return f16mat4x3(val.col0, val.col1, val.col2, val.col3);
 }
@@ -31,8 +47,9 @@
 }
 
 void f() {
-  s.inner = conv_arr4_mat4x3_f16(u.inner);
-  s.inner[1] = conv_mat4x3_f16(u.inner[2u]);
+  assign_and_preserve_padding_s(conv_arr4_mat4x3_f16(u.inner));
+  uint tint_symbol_1[1] = uint[1](1u);
+  assign_and_preserve_padding_1_s_X(tint_symbol_1, conv_mat4x3_f16(u.inner[2u]));
   s.inner[1][0] = u.inner[0u].col1.zxy;
   s.inner[1][0].x = u.inner[0u].col1[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_storage.wgsl.expected.msl
index 7405552..3e19776 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_storage.wgsl.expected.msl
@@ -14,9 +14,22 @@
     T elements[N];
 };
 
+void assign_and_preserve_padding_1(device half4x3* const dest, half4x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+  (*(dest))[3u] = value[3u];
+}
+
+void assign_and_preserve_padding(device tint_array<half4x3, 4>* const dest, tint_array<half4x3, 4> value) {
+  for(uint i = 0u; (i < 4u); i = (i + 1u)) {
+    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+  }
+}
+
 kernel void f(device tint_array<half4x3, 4>* tint_symbol [[buffer(1)]], const constant tint_array<half4x3, 4>* tint_symbol_1 [[buffer(0)]]) {
-  *(tint_symbol) = *(tint_symbol_1);
-  (*(tint_symbol))[1] = (*(tint_symbol_1))[2];
+  assign_and_preserve_padding(tint_symbol, *(tint_symbol_1));
+  assign_and_preserve_padding_1(&((*(tint_symbol))[1]), (*(tint_symbol_1))[2]);
   (*(tint_symbol))[1][0] = half3((*(tint_symbol_1))[0][1]).zxy;
   (*(tint_symbol))[1][0][0] = (*(tint_symbol_1))[0][1][0];
   return;
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_storage.wgsl.expected.spvasm
index cb52845..32ed3ef 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 91
+; Bound: 134
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -22,13 +22,20 @@
                OpName %u_block "u_block"
                OpMemberName %u_block 0 "inner"
                OpName %s "s"
+               OpName %assign_and_preserve_padding_1_s_X "assign_and_preserve_padding_1_s_X"
+               OpName %dest "dest"
+               OpName %value "value"
+               OpName %assign_and_preserve_padding_s "assign_and_preserve_padding_s"
+               OpName %value_0 "value"
+               OpName %i "i"
+               OpName %var_for_index "var_for_index"
                OpName %conv_mat4x3_f16 "conv_mat4x3_f16"
                OpName %val "val"
                OpName %conv_arr4_mat4x3_f16 "conv_arr4_mat4x3_f16"
                OpName %val_0 "val"
                OpName %arr "arr"
-               OpName %i "i"
-               OpName %var_for_index "var_for_index"
+               OpName %i_0 "i"
+               OpName %var_for_index_1 "var_for_index_1"
                OpName %f "f"
                OpDecorate %u_block_std140 Block
                OpMemberDecorate %u_block_std140 0 Offset 0
@@ -47,6 +54,7 @@
                OpDecorate %_arr_mat4v3half_uint_4 ArrayStride 32
                OpDecorate %s DescriptorSet 0
                OpDecorate %s Binding 1
+               OpDecorate %_arr_uint_uint_1 ArrayStride 4
        %half = OpTypeFloat 16
      %v3half = OpTypeVector %half 3
  %mat4x3_f16 = OpTypeStruct %v3half %v3half %v3half %v3half
@@ -61,100 +69,160 @@
     %u_block = OpTypeStruct %_arr_mat4v3half_uint_4
 %_ptr_StorageBuffer_u_block = OpTypePointer StorageBuffer %u_block
           %s = OpVariable %_ptr_StorageBuffer_u_block StorageBuffer
-         %15 = OpTypeFunction %mat4v3half %mat4x3_f16
-         %24 = OpTypeFunction %_arr_mat4v3half_uint_4 %_arr_mat4x3_f16_uint_4
-%_ptr_Function__arr_mat4v3half_uint_4 = OpTypePointer Function %_arr_mat4v3half_uint_4
-         %30 = OpConstantNull %_arr_mat4v3half_uint_4
-%_ptr_Function_uint = OpTypePointer Function %uint
-         %33 = OpConstantNull %uint
-       %bool = OpTypeBool
-%_ptr_Function__arr_mat4x3_f16_uint_4 = OpTypePointer Function %_arr_mat4x3_f16_uint_4
-         %46 = OpConstantNull %_arr_mat4x3_f16_uint_4
-%_ptr_Function_mat4v3half = OpTypePointer Function %mat4v3half
-%_ptr_Function_mat4x3_f16 = OpTypePointer Function %mat4x3_f16
-     %uint_1 = OpConstant %uint 1
        %void = OpTypeVoid
-         %59 = OpTypeFunction %void
+     %uint_1 = OpConstant %uint 1
+%_arr_uint_uint_1 = OpTypeArray %uint %uint_1
+         %15 = OpTypeFunction %void %_arr_uint_uint_1 %mat4v3half
      %uint_0 = OpConstant %uint 0
-%_ptr_StorageBuffer__arr_mat4v3half_uint_4 = OpTypePointer StorageBuffer %_arr_mat4v3half_uint_4
-%_ptr_Uniform__arr_mat4x3_f16_uint_4 = OpTypePointer Uniform %_arr_mat4x3_f16_uint_4
         %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-%_ptr_StorageBuffer_mat4v3half = OpTypePointer StorageBuffer %mat4v3half
-     %uint_2 = OpConstant %uint 2
-%_ptr_Uniform_mat4x3_f16 = OpTypePointer Uniform %mat4x3_f16
-         %79 = OpConstantNull %int
+         %25 = OpConstantNull %int
 %_ptr_StorageBuffer_v3half = OpTypePointer StorageBuffer %v3half
+         %29 = OpConstantNull %uint
+      %int_1 = OpConstant %int 1
+      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
+      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
+         %45 = OpTypeFunction %void %_arr_mat4v3half_uint_4
+%_ptr_Function_uint = OpTypePointer Function %uint
+       %bool = OpTypeBool
+%_ptr_Function__arr_mat4v3half_uint_4 = OpTypePointer Function %_arr_mat4v3half_uint_4
+         %63 = OpConstantNull %_arr_mat4v3half_uint_4
+%_ptr_Function_mat4v3half = OpTypePointer Function %mat4v3half
+         %73 = OpTypeFunction %mat4v3half %mat4x3_f16
+         %82 = OpTypeFunction %_arr_mat4v3half_uint_4 %_arr_mat4x3_f16_uint_4
+%_ptr_Function__arr_mat4x3_f16_uint_4 = OpTypePointer Function %_arr_mat4x3_f16_uint_4
+         %99 = OpConstantNull %_arr_mat4x3_f16_uint_4
+%_ptr_Function_mat4x3_f16 = OpTypePointer Function %mat4x3_f16
+        %110 = OpTypeFunction %void
+%_ptr_Uniform__arr_mat4x3_f16_uint_4 = OpTypePointer Uniform %_arr_mat4x3_f16_uint_4
+        %119 = OpConstantComposite %_arr_uint_uint_1 %uint_1
+%_ptr_Uniform_mat4x3_f16 = OpTypePointer Uniform %mat4x3_f16
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
 %_ptr_Uniform_half = OpTypePointer Uniform %half
-%conv_mat4x3_f16 = OpFunction %mat4v3half None %15
+%assign_and_preserve_padding_1_s_X = OpFunction %void None %15
+       %dest = OpFunctionParameter %_arr_uint_uint_1
+      %value = OpFunctionParameter %mat4v3half
+         %22 = OpLabel
+         %26 = OpCompositeExtract %uint %dest 0
+         %28 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %26 %25
+         %30 = OpCompositeExtract %v3half %value 0
+               OpStore %28 %30
+         %31 = OpCompositeExtract %uint %dest 0
+         %33 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %31 %int_1
+         %34 = OpCompositeExtract %v3half %value 1
+               OpStore %33 %34
+         %35 = OpCompositeExtract %uint %dest 0
+         %37 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %35 %int_2
+         %39 = OpCompositeExtract %v3half %value 2
+               OpStore %37 %39
+         %40 = OpCompositeExtract %uint %dest 0
+         %42 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %40 %int_3
+         %44 = OpCompositeExtract %v3half %value 3
+               OpStore %42 %44
+               OpReturn
+               OpFunctionEnd
+%assign_and_preserve_padding_s = OpFunction %void None %45
+    %value_0 = OpFunctionParameter %_arr_mat4v3half_uint_4
+         %48 = OpLabel
+          %i = OpVariable %_ptr_Function_uint Function %29
+%var_for_index = OpVariable %_ptr_Function__arr_mat4v3half_uint_4 Function %63
+               OpStore %i %29
+               OpBranch %51
+         %51 = OpLabel
+               OpLoopMerge %52 %53 None
+               OpBranch %54
+         %54 = OpLabel
+         %56 = OpLoad %uint %i
+         %57 = OpULessThan %bool %56 %uint_4
+         %55 = OpLogicalNot %bool %57
+               OpSelectionMerge %59 None
+               OpBranchConditional %55 %60 %59
+         %60 = OpLabel
+               OpBranch %52
+         %59 = OpLabel
+               OpStore %var_for_index %value_0
+         %65 = OpLoad %uint %i
+         %66 = OpCompositeConstruct %_arr_uint_uint_1 %65
+         %67 = OpLoad %uint %i
+         %69 = OpAccessChain %_ptr_Function_mat4v3half %var_for_index %67
+         %70 = OpLoad %mat4v3half %69
+         %64 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %66 %70
+               OpBranch %53
+         %53 = OpLabel
+         %71 = OpLoad %uint %i
+         %72 = OpIAdd %uint %71 %uint_1
+               OpStore %i %72
+               OpBranch %51
+         %52 = OpLabel
+               OpReturn
+               OpFunctionEnd
+%conv_mat4x3_f16 = OpFunction %mat4v3half None %73
         %val = OpFunctionParameter %mat4x3_f16
-         %18 = OpLabel
-         %19 = OpCompositeExtract %v3half %val 0
-         %20 = OpCompositeExtract %v3half %val 1
-         %21 = OpCompositeExtract %v3half %val 2
-         %22 = OpCompositeExtract %v3half %val 3
-         %23 = OpCompositeConstruct %mat4v3half %19 %20 %21 %22
-               OpReturnValue %23
+         %76 = OpLabel
+         %77 = OpCompositeExtract %v3half %val 0
+         %78 = OpCompositeExtract %v3half %val 1
+         %79 = OpCompositeExtract %v3half %val 2
+         %80 = OpCompositeExtract %v3half %val 3
+         %81 = OpCompositeConstruct %mat4v3half %77 %78 %79 %80
+               OpReturnValue %81
                OpFunctionEnd
-%conv_arr4_mat4x3_f16 = OpFunction %_arr_mat4v3half_uint_4 None %24
+%conv_arr4_mat4x3_f16 = OpFunction %_arr_mat4v3half_uint_4 None %82
       %val_0 = OpFunctionParameter %_arr_mat4x3_f16_uint_4
-         %27 = OpLabel
-        %arr = OpVariable %_ptr_Function__arr_mat4v3half_uint_4 Function %30
-          %i = OpVariable %_ptr_Function_uint Function %33
-%var_for_index = OpVariable %_ptr_Function__arr_mat4x3_f16_uint_4 Function %46
-               OpBranch %34
-         %34 = OpLabel
-               OpLoopMerge %35 %36 None
-               OpBranch %37
-         %37 = OpLabel
-         %39 = OpLoad %uint %i
-         %40 = OpULessThan %bool %39 %uint_4
-         %38 = OpLogicalNot %bool %40
-               OpSelectionMerge %42 None
-               OpBranchConditional %38 %43 %42
-         %43 = OpLabel
-               OpBranch %35
-         %42 = OpLabel
-               OpStore %var_for_index %val_0
-         %47 = OpLoad %uint %i
-         %49 = OpAccessChain %_ptr_Function_mat4v3half %arr %47
-         %51 = OpLoad %uint %i
-         %53 = OpAccessChain %_ptr_Function_mat4x3_f16 %var_for_index %51
-         %54 = OpLoad %mat4x3_f16 %53
-         %50 = OpFunctionCall %mat4v3half %conv_mat4x3_f16 %54
-               OpStore %49 %50
-               OpBranch %36
-         %36 = OpLabel
-         %55 = OpLoad %uint %i
-         %57 = OpIAdd %uint %55 %uint_1
-               OpStore %i %57
-               OpBranch %34
-         %35 = OpLabel
-         %58 = OpLoad %_arr_mat4v3half_uint_4 %arr
-               OpReturnValue %58
+         %85 = OpLabel
+        %arr = OpVariable %_ptr_Function__arr_mat4v3half_uint_4 Function %63
+        %i_0 = OpVariable %_ptr_Function_uint Function %29
+%var_for_index_1 = OpVariable %_ptr_Function__arr_mat4x3_f16_uint_4 Function %99
+               OpBranch %88
+         %88 = OpLabel
+               OpLoopMerge %89 %90 None
+               OpBranch %91
+         %91 = OpLabel
+         %93 = OpLoad %uint %i_0
+         %94 = OpULessThan %bool %93 %uint_4
+         %92 = OpLogicalNot %bool %94
+               OpSelectionMerge %95 None
+               OpBranchConditional %92 %96 %95
+         %96 = OpLabel
+               OpBranch %89
+         %95 = OpLabel
+               OpStore %var_for_index_1 %val_0
+        %100 = OpLoad %uint %i_0
+        %101 = OpAccessChain %_ptr_Function_mat4v3half %arr %100
+        %103 = OpLoad %uint %i_0
+        %105 = OpAccessChain %_ptr_Function_mat4x3_f16 %var_for_index_1 %103
+        %106 = OpLoad %mat4x3_f16 %105
+        %102 = OpFunctionCall %mat4v3half %conv_mat4x3_f16 %106
+               OpStore %101 %102
+               OpBranch %90
+         %90 = OpLabel
+        %107 = OpLoad %uint %i_0
+        %108 = OpIAdd %uint %107 %uint_1
+               OpStore %i_0 %108
+               OpBranch %88
+         %89 = OpLabel
+        %109 = OpLoad %_arr_mat4v3half_uint_4 %arr
+               OpReturnValue %109
                OpFunctionEnd
-          %f = OpFunction %void None %59
-         %62 = OpLabel
-         %65 = OpAccessChain %_ptr_StorageBuffer__arr_mat4v3half_uint_4 %s %uint_0
-         %68 = OpAccessChain %_ptr_Uniform__arr_mat4x3_f16_uint_4 %u %uint_0
-         %69 = OpLoad %_arr_mat4x3_f16_uint_4 %68
-         %66 = OpFunctionCall %_arr_mat4v3half_uint_4 %conv_arr4_mat4x3_f16 %69
-               OpStore %65 %66
-         %73 = OpAccessChain %_ptr_StorageBuffer_mat4v3half %s %uint_0 %int_1
-         %77 = OpAccessChain %_ptr_Uniform_mat4x3_f16 %u %uint_0 %uint_2
-         %78 = OpLoad %mat4x3_f16 %77
-         %74 = OpFunctionCall %mat4v3half %conv_mat4x3_f16 %78
-               OpStore %73 %74
-         %81 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %int_1 %79
-         %83 = OpAccessChain %_ptr_Uniform_v3half %u %uint_0 %33 %uint_1
-         %84 = OpLoad %v3half %83
-         %85 = OpVectorShuffle %v3half %84 %84 2 0 1
-               OpStore %81 %85
-         %87 = OpAccessChain %_ptr_StorageBuffer_half %s %uint_0 %int_1 %79 %uint_0
-         %89 = OpAccessChain %_ptr_Uniform_half %u %uint_0 %33 %uint_1 %33
-         %90 = OpLoad %half %89
-               OpStore %87 %90
+          %f = OpFunction %void None %110
+        %112 = OpLabel
+        %116 = OpAccessChain %_ptr_Uniform__arr_mat4x3_f16_uint_4 %u %uint_0
+        %117 = OpLoad %_arr_mat4x3_f16_uint_4 %116
+        %114 = OpFunctionCall %_arr_mat4v3half_uint_4 %conv_arr4_mat4x3_f16 %117
+        %113 = OpFunctionCall %void %assign_and_preserve_padding_s %114
+        %122 = OpAccessChain %_ptr_Uniform_mat4x3_f16 %u %uint_0 %uint_2
+        %123 = OpLoad %mat4x3_f16 %122
+        %120 = OpFunctionCall %mat4v3half %conv_mat4x3_f16 %123
+        %118 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %119 %120
+        %124 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %int_1 %25
+        %126 = OpAccessChain %_ptr_Uniform_v3half %u %uint_0 %29 %uint_1
+        %127 = OpLoad %v3half %126
+        %128 = OpVectorShuffle %v3half %127 %127 2 0 1
+               OpStore %124 %128
+        %130 = OpAccessChain %_ptr_StorageBuffer_half %s %uint_0 %int_1 %25 %uint_0
+        %132 = OpAccessChain %_ptr_Uniform_half %u %uint_0 %29 %uint_1 %29
+        %133 = OpLoad %half %132
+               OpStore %130 %133
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_storage.wgsl.expected.glsl
index eb0649d..272368a 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_storage.wgsl.expected.glsl
@@ -8,9 +8,26 @@
   mat4x3 inner[4];
 } s;
 
+void assign_and_preserve_padding_1_s_X(uint dest[1], mat4x3 value) {
+  s.inner[dest[0]][0] = value[0u];
+  s.inner[dest[0]][1] = value[1u];
+  s.inner[dest[0]][2] = value[2u];
+  s.inner[dest[0]][3] = value[3u];
+}
+
+void assign_and_preserve_padding_s(mat4x3 value[4]) {
+  {
+    for(uint i = 0u; (i < 4u); i = (i + 1u)) {
+      uint tint_symbol[1] = uint[1](i);
+      assign_and_preserve_padding_1_s_X(tint_symbol, value[i]);
+    }
+  }
+}
+
 void f() {
-  s.inner = u.inner;
-  s.inner[1] = u.inner[2];
+  assign_and_preserve_padding_s(u.inner);
+  uint tint_symbol_1[1] = uint[1](1u);
+  assign_and_preserve_padding_1_s_X(tint_symbol_1, u.inner[2]);
   s.inner[1][0] = u.inner[0][1].zxy;
   s.inner[1][0].x = u.inner[0][1].x;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_storage.wgsl.expected.msl
index 05cfa2f..d9eba4b 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_storage.wgsl.expected.msl
@@ -14,9 +14,22 @@
     T elements[N];
 };
 
+void assign_and_preserve_padding_1(device float4x3* const dest, float4x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+  (*(dest))[3u] = value[3u];
+}
+
+void assign_and_preserve_padding(device tint_array<float4x3, 4>* const dest, tint_array<float4x3, 4> value) {
+  for(uint i = 0u; (i < 4u); i = (i + 1u)) {
+    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+  }
+}
+
 kernel void f(device tint_array<float4x3, 4>* tint_symbol [[buffer(1)]], const constant tint_array<float4x3, 4>* tint_symbol_1 [[buffer(0)]]) {
-  *(tint_symbol) = *(tint_symbol_1);
-  (*(tint_symbol))[1] = (*(tint_symbol_1))[2];
+  assign_and_preserve_padding(tint_symbol, *(tint_symbol_1));
+  assign_and_preserve_padding_1(&((*(tint_symbol))[1]), (*(tint_symbol_1))[2]);
   (*(tint_symbol))[1][0] = float3((*(tint_symbol_1))[0][1]).zxy;
   (*(tint_symbol))[1][0][0] = (*(tint_symbol_1))[0][1][0];
   return;
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_storage.wgsl.expected.spvasm
index 061e9a9..5865104 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 42
+; Bound: 92
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -11,6 +11,13 @@
                OpMemberName %u_block 0 "inner"
                OpName %u "u"
                OpName %s "s"
+               OpName %assign_and_preserve_padding_1_s_X "assign_and_preserve_padding_1_s_X"
+               OpName %dest "dest"
+               OpName %value "value"
+               OpName %assign_and_preserve_padding_s "assign_and_preserve_padding_s"
+               OpName %value_0 "value"
+               OpName %i "i"
+               OpName %var_for_index "var_for_index"
                OpName %f "f"
                OpDecorate %u_block Block
                OpMemberDecorate %u_block 0 Offset 0
@@ -22,6 +29,7 @@
                OpDecorate %u Binding 0
                OpDecorate %s DescriptorSet 0
                OpDecorate %s Binding 1
+               OpDecorate %_arr_uint_uint_1 ArrayStride 4
       %float = OpTypeFloat 32
     %v3float = OpTypeVector %float 3
 %mat4v3float = OpTypeMatrix %v3float 4
@@ -34,38 +42,105 @@
 %_ptr_StorageBuffer_u_block = OpTypePointer StorageBuffer %u_block
           %s = OpVariable %_ptr_StorageBuffer_u_block StorageBuffer
        %void = OpTypeVoid
-         %12 = OpTypeFunction %void
+     %uint_1 = OpConstant %uint 1
+%_arr_uint_uint_1 = OpTypeArray %uint %uint_1
+         %12 = OpTypeFunction %void %_arr_uint_uint_1 %mat4v3float
      %uint_0 = OpConstant %uint 0
-%_ptr_StorageBuffer__arr_mat4v3float_uint_4 = OpTypePointer StorageBuffer %_arr_mat4v3float_uint_4
-%_ptr_Uniform__arr_mat4v3float_uint_4 = OpTypePointer Uniform %_arr_mat4v3float_uint_4
         %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-%_ptr_StorageBuffer_mat4v3float = OpTypePointer StorageBuffer %mat4v3float
-      %int_2 = OpConstant %int 2
-%_ptr_Uniform_mat4v3float = OpTypePointer Uniform %mat4v3float
-         %30 = OpConstantNull %int
+         %22 = OpConstantNull %int
 %_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
+         %26 = OpConstantNull %uint
+      %int_1 = OpConstant %int 1
+      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
+      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
+         %42 = OpTypeFunction %void %_arr_mat4v3float_uint_4
+%_ptr_Function_uint = OpTypePointer Function %uint
+       %bool = OpTypeBool
+%_ptr_Function__arr_mat4v3float_uint_4 = OpTypePointer Function %_arr_mat4v3float_uint_4
+         %60 = OpConstantNull %_arr_mat4v3float_uint_4
+%_ptr_Function_mat4v3float = OpTypePointer Function %mat4v3float
+         %70 = OpTypeFunction %void
+%_ptr_Uniform__arr_mat4v3float_uint_4 = OpTypePointer Uniform %_arr_mat4v3float_uint_4
+         %78 = OpConstantComposite %_arr_uint_uint_1 %uint_1
+%_ptr_Uniform_mat4v3float = OpTypePointer Uniform %mat4v3float
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
 %_ptr_Uniform_float = OpTypePointer Uniform %float
-          %f = OpFunction %void None %12
-         %15 = OpLabel
-         %18 = OpAccessChain %_ptr_StorageBuffer__arr_mat4v3float_uint_4 %s %uint_0
-         %20 = OpAccessChain %_ptr_Uniform__arr_mat4v3float_uint_4 %u %uint_0
-         %21 = OpLoad %_arr_mat4v3float_uint_4 %20
-               OpStore %18 %21
-         %25 = OpAccessChain %_ptr_StorageBuffer_mat4v3float %s %uint_0 %int_1
-         %28 = OpAccessChain %_ptr_Uniform_mat4v3float %u %uint_0 %int_2
-         %29 = OpLoad %mat4v3float %28
-               OpStore %25 %29
-         %32 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %int_1 %30
-         %34 = OpAccessChain %_ptr_Uniform_v3float %u %uint_0 %30 %int_1
-         %35 = OpLoad %v3float %34
-         %36 = OpVectorShuffle %v3float %35 %35 2 0 1
-               OpStore %32 %36
-         %38 = OpAccessChain %_ptr_StorageBuffer_float %s %uint_0 %int_1 %30 %uint_0
-         %40 = OpAccessChain %_ptr_Uniform_float %u %uint_0 %30 %int_1 %uint_0
-         %41 = OpLoad %float %40
-               OpStore %38 %41
+%assign_and_preserve_padding_1_s_X = OpFunction %void None %12
+       %dest = OpFunctionParameter %_arr_uint_uint_1
+      %value = OpFunctionParameter %mat4v3float
+         %19 = OpLabel
+         %23 = OpCompositeExtract %uint %dest 0
+         %25 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %23 %22
+         %27 = OpCompositeExtract %v3float %value 0
+               OpStore %25 %27
+         %28 = OpCompositeExtract %uint %dest 0
+         %30 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %28 %int_1
+         %31 = OpCompositeExtract %v3float %value 1
+               OpStore %30 %31
+         %32 = OpCompositeExtract %uint %dest 0
+         %34 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %32 %int_2
+         %36 = OpCompositeExtract %v3float %value 2
+               OpStore %34 %36
+         %37 = OpCompositeExtract %uint %dest 0
+         %39 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %37 %int_3
+         %41 = OpCompositeExtract %v3float %value 3
+               OpStore %39 %41
+               OpReturn
+               OpFunctionEnd
+%assign_and_preserve_padding_s = OpFunction %void None %42
+    %value_0 = OpFunctionParameter %_arr_mat4v3float_uint_4
+         %45 = OpLabel
+          %i = OpVariable %_ptr_Function_uint Function %26
+%var_for_index = OpVariable %_ptr_Function__arr_mat4v3float_uint_4 Function %60
+               OpStore %i %26
+               OpBranch %48
+         %48 = OpLabel
+               OpLoopMerge %49 %50 None
+               OpBranch %51
+         %51 = OpLabel
+         %53 = OpLoad %uint %i
+         %54 = OpULessThan %bool %53 %uint_4
+         %52 = OpLogicalNot %bool %54
+               OpSelectionMerge %56 None
+               OpBranchConditional %52 %57 %56
+         %57 = OpLabel
+               OpBranch %49
+         %56 = OpLabel
+               OpStore %var_for_index %value_0
+         %62 = OpLoad %uint %i
+         %63 = OpCompositeConstruct %_arr_uint_uint_1 %62
+         %64 = OpLoad %uint %i
+         %66 = OpAccessChain %_ptr_Function_mat4v3float %var_for_index %64
+         %67 = OpLoad %mat4v3float %66
+         %61 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %63 %67
+               OpBranch %50
+         %50 = OpLabel
+         %68 = OpLoad %uint %i
+         %69 = OpIAdd %uint %68 %uint_1
+               OpStore %i %69
+               OpBranch %48
+         %49 = OpLabel
+               OpReturn
+               OpFunctionEnd
+          %f = OpFunction %void None %70
+         %72 = OpLabel
+         %75 = OpAccessChain %_ptr_Uniform__arr_mat4v3float_uint_4 %u %uint_0
+         %76 = OpLoad %_arr_mat4v3float_uint_4 %75
+         %73 = OpFunctionCall %void %assign_and_preserve_padding_s %76
+         %80 = OpAccessChain %_ptr_Uniform_mat4v3float %u %uint_0 %int_2
+         %81 = OpLoad %mat4v3float %80
+         %77 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %78 %81
+         %82 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %int_1 %22
+         %84 = OpAccessChain %_ptr_Uniform_v3float %u %uint_0 %22 %int_1
+         %85 = OpLoad %v3float %84
+         %86 = OpVectorShuffle %v3float %85 %85 2 0 1
+               OpStore %82 %86
+         %88 = OpAccessChain %_ptr_StorageBuffer_float %s %uint_0 %int_1 %22 %uint_0
+         %90 = OpAccessChain %_ptr_Uniform_float %u %uint_0 %22 %int_1 %uint_0
+         %91 = OpLoad %float %90
+               OpStore %88 %91
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_storage.wgsl.expected.glsl
index 8847feb..02a6f08 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_storage.wgsl.expected.glsl
@@ -74,17 +74,23 @@
   S inner[4];
 } s;
 
+void assign_and_preserve_padding_2_s_X_m(uint dest[1], f16mat2x3 value) {
+  s.inner[dest[0]].m[0] = value[0u];
+  s.inner[dest[0]].m[1] = value[1u];
+}
+
 void assign_and_preserve_padding_1_s_X(uint dest[1], S value) {
   s.inner[dest[0]].before = value.before;
-  s.inner[dest[0]].m = value.m;
+  uint tint_symbol[1] = uint[1](dest[0u]);
+  assign_and_preserve_padding_2_s_X_m(tint_symbol, value.m);
   s.inner[dest[0]].after = value.after;
 }
 
 void assign_and_preserve_padding_s(S value[4]) {
   {
     for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-      uint tint_symbol[1] = uint[1](i);
-      assign_and_preserve_padding_1_s_X(tint_symbol, value[i]);
+      uint tint_symbol_1[1] = uint[1](i);
+      assign_and_preserve_padding_1_s_X(tint_symbol_1, value[i]);
     }
   }
 }
@@ -109,9 +115,10 @@
 
 void f() {
   assign_and_preserve_padding_s(conv_arr4_S(u.inner));
-  uint tint_symbol_1[1] = uint[1](1u);
-  assign_and_preserve_padding_1_s_X(tint_symbol_1, conv_S(u.inner[2u]));
-  s.inner[3].m = load_u_inner_2_m();
+  uint tint_symbol_2[1] = uint[1](1u);
+  assign_and_preserve_padding_1_s_X(tint_symbol_2, conv_S(u.inner[2u]));
+  uint tint_symbol_3[1] = uint[1](3u);
+  assign_and_preserve_padding_2_s_X_m(tint_symbol_3, load_u_inner_2_m());
   s.inner[1].m[0] = u.inner[0u].m_1.zxy;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_storage.wgsl.expected.msl
index 30cb485..a574012 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_storage.wgsl.expected.msl
@@ -23,9 +23,14 @@
   /* 0x0044 */ tint_array<int8_t, 60> tint_pad_2;
 };
 
+void assign_and_preserve_padding_2(device half2x3* const dest, half2x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+}
+
 void assign_and_preserve_padding_1(device S* const dest, S value) {
   (*(dest)).before = value.before;
-  (*(dest)).m = value.m;
+  assign_and_preserve_padding_2(&((*(dest)).m), value.m);
   (*(dest)).after = value.after;
 }
 
@@ -38,7 +43,7 @@
 kernel void f(device tint_array<S, 4>* tint_symbol [[buffer(1)]], const constant tint_array<S, 4>* tint_symbol_1 [[buffer(0)]]) {
   assign_and_preserve_padding(tint_symbol, *(tint_symbol_1));
   assign_and_preserve_padding_1(&((*(tint_symbol))[1]), (*(tint_symbol_1))[2]);
-  (*(tint_symbol))[3].m = (*(tint_symbol_1))[2].m;
+  assign_and_preserve_padding_2(&((*(tint_symbol))[3].m), (*(tint_symbol_1))[2].m);
   (*(tint_symbol))[1].m[0] = half3((*(tint_symbol_1))[0].m[1]).zxy;
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_storage.wgsl.expected.spvasm
index 670184c..4a91949 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 142
+; Bound: 154
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -26,11 +26,14 @@
                OpMemberName %S 1 "m"
                OpMemberName %S 2 "after"
                OpName %s "s"
-               OpName %assign_and_preserve_padding_1_s_X "assign_and_preserve_padding_1_s_X"
+               OpName %assign_and_preserve_padding_2_s_X_m "assign_and_preserve_padding_2_s_X_m"
                OpName %dest "dest"
                OpName %value "value"
-               OpName %assign_and_preserve_padding_s "assign_and_preserve_padding_s"
+               OpName %assign_and_preserve_padding_1_s_X "assign_and_preserve_padding_1_s_X"
+               OpName %dest_0 "dest"
                OpName %value_0 "value"
+               OpName %assign_and_preserve_padding_s "assign_and_preserve_padding_s"
+               OpName %value_1 "value"
                OpName %i "i"
                OpName %var_for_index "var_for_index"
                OpName %conv_S "conv_S"
@@ -82,161 +85,175 @@
        %void = OpTypeVoid
      %uint_1 = OpConstant %uint 1
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
-         %17 = OpTypeFunction %void %_arr_uint_uint_1 %S
+         %17 = OpTypeFunction %void %_arr_uint_uint_1 %mat2v3half
      %uint_0 = OpConstant %uint 0
          %26 = OpConstantNull %int
+%_ptr_StorageBuffer_v3half = OpTypePointer StorageBuffer %v3half
+         %30 = OpConstantNull %uint
+      %int_1 = OpConstant %int 1
+         %36 = OpTypeFunction %void %_arr_uint_uint_1 %S
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-%_ptr_StorageBuffer_mat2v3half = OpTypePointer StorageBuffer %mat2v3half
      %uint_2 = OpConstant %uint 2
-         %39 = OpTypeFunction %void %_arr_S_uint_4
-         %43 = OpConstantNull %uint
+         %53 = OpTypeFunction %void %_arr_S_uint_4
 %_ptr_Function_uint = OpTypePointer Function %uint
        %bool = OpTypeBool
 %_ptr_Function__arr_S_uint_4 = OpTypePointer Function %_arr_S_uint_4
-         %58 = OpConstantNull %_arr_S_uint_4
+         %71 = OpConstantNull %_arr_S_uint_4
 %_ptr_Function_S = OpTypePointer Function %S
-         %68 = OpTypeFunction %S %S_std140
-         %78 = OpTypeFunction %_arr_S_uint_4 %_arr_S_std140_uint_4
+         %81 = OpTypeFunction %S %S_std140
+         %91 = OpTypeFunction %_arr_S_uint_4 %_arr_S_std140_uint_4
 %_ptr_Function__arr_S_std140_uint_4 = OpTypePointer Function %_arr_S_std140_uint_4
-         %95 = OpConstantNull %_arr_S_std140_uint_4
+        %108 = OpConstantNull %_arr_S_std140_uint_4
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
-        %106 = OpTypeFunction %mat2v3half
+        %119 = OpTypeFunction %mat2v3half
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
-        %120 = OpTypeFunction %void
+        %133 = OpTypeFunction %void
 %_ptr_Uniform__arr_S_std140_uint_4 = OpTypePointer Uniform %_arr_S_std140_uint_4
-        %129 = OpConstantComposite %_arr_uint_uint_1 %uint_1
-      %int_3 = OpConstant %int 3
-      %int_1 = OpConstant %int 1
-%_ptr_StorageBuffer_v3half = OpTypePointer StorageBuffer %v3half
-%assign_and_preserve_padding_1_s_X = OpFunction %void None %17
+        %142 = OpConstantComposite %_arr_uint_uint_1 %uint_1
+     %uint_3 = OpConstant %uint 3
+        %148 = OpConstantComposite %_arr_uint_uint_1 %uint_3
+%assign_and_preserve_padding_2_s_X_m = OpFunction %void None %17
        %dest = OpFunctionParameter %_arr_uint_uint_1
-      %value = OpFunctionParameter %S
+      %value = OpFunctionParameter %mat2v3half
          %24 = OpLabel
          %27 = OpCompositeExtract %uint %dest 0
-         %29 = OpAccessChain %_ptr_StorageBuffer_int %s %uint_0 %27 %uint_0
-         %30 = OpCompositeExtract %int %value 0
-               OpStore %29 %30
-         %31 = OpCompositeExtract %uint %dest 0
-         %33 = OpAccessChain %_ptr_StorageBuffer_mat2v3half %s %uint_0 %31 %uint_1
-         %34 = OpCompositeExtract %mat2v3half %value 1
-               OpStore %33 %34
-         %35 = OpCompositeExtract %uint %dest 0
-         %37 = OpAccessChain %_ptr_StorageBuffer_int %s %uint_0 %35 %uint_2
-         %38 = OpCompositeExtract %int %value 2
-               OpStore %37 %38
+         %29 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %27 %uint_1 %26
+         %31 = OpCompositeExtract %v3half %value 0
+               OpStore %29 %31
+         %32 = OpCompositeExtract %uint %dest 0
+         %34 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %32 %uint_1 %int_1
+         %35 = OpCompositeExtract %v3half %value 1
+               OpStore %34 %35
                OpReturn
                OpFunctionEnd
-%assign_and_preserve_padding_s = OpFunction %void None %39
-    %value_0 = OpFunctionParameter %_arr_S_uint_4
-         %42 = OpLabel
-          %i = OpVariable %_ptr_Function_uint Function %43
-%var_for_index = OpVariable %_ptr_Function__arr_S_uint_4 Function %58
-               OpStore %i %43
-               OpBranch %46
-         %46 = OpLabel
-               OpLoopMerge %47 %48 None
-               OpBranch %49
-         %49 = OpLabel
-         %51 = OpLoad %uint %i
-         %52 = OpULessThan %bool %51 %uint_4
-         %50 = OpLogicalNot %bool %52
-               OpSelectionMerge %54 None
-               OpBranchConditional %50 %55 %54
-         %55 = OpLabel
-               OpBranch %47
-         %54 = OpLabel
-               OpStore %var_for_index %value_0
-         %60 = OpLoad %uint %i
-         %61 = OpCompositeConstruct %_arr_uint_uint_1 %60
-         %62 = OpLoad %uint %i
-         %64 = OpAccessChain %_ptr_Function_S %var_for_index %62
-         %65 = OpLoad %S %64
-         %59 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %61 %65
-               OpBranch %48
-         %48 = OpLabel
-         %66 = OpLoad %uint %i
-         %67 = OpIAdd %uint %66 %uint_1
-               OpStore %i %67
-               OpBranch %46
-         %47 = OpLabel
+%assign_and_preserve_padding_1_s_X = OpFunction %void None %36
+     %dest_0 = OpFunctionParameter %_arr_uint_uint_1
+    %value_0 = OpFunctionParameter %S
+         %40 = OpLabel
+         %41 = OpCompositeExtract %uint %dest_0 0
+         %43 = OpAccessChain %_ptr_StorageBuffer_int %s %uint_0 %41 %uint_0
+         %44 = OpCompositeExtract %int %value_0 0
+               OpStore %43 %44
+         %46 = OpCompositeExtract %uint %dest_0 0
+         %47 = OpCompositeConstruct %_arr_uint_uint_1 %46
+         %48 = OpCompositeExtract %mat2v3half %value_0 1
+         %45 = OpFunctionCall %void %assign_and_preserve_padding_2_s_X_m %47 %48
+         %49 = OpCompositeExtract %uint %dest_0 0
+         %51 = OpAccessChain %_ptr_StorageBuffer_int %s %uint_0 %49 %uint_2
+         %52 = OpCompositeExtract %int %value_0 2
+               OpStore %51 %52
                OpReturn
                OpFunctionEnd
-     %conv_S = OpFunction %S None %68
+%assign_and_preserve_padding_s = OpFunction %void None %53
+    %value_1 = OpFunctionParameter %_arr_S_uint_4
+         %56 = OpLabel
+          %i = OpVariable %_ptr_Function_uint Function %30
+%var_for_index = OpVariable %_ptr_Function__arr_S_uint_4 Function %71
+               OpStore %i %30
+               OpBranch %59
+         %59 = OpLabel
+               OpLoopMerge %60 %61 None
+               OpBranch %62
+         %62 = OpLabel
+         %64 = OpLoad %uint %i
+         %65 = OpULessThan %bool %64 %uint_4
+         %63 = OpLogicalNot %bool %65
+               OpSelectionMerge %67 None
+               OpBranchConditional %63 %68 %67
+         %68 = OpLabel
+               OpBranch %60
+         %67 = OpLabel
+               OpStore %var_for_index %value_1
+         %73 = OpLoad %uint %i
+         %74 = OpCompositeConstruct %_arr_uint_uint_1 %73
+         %75 = OpLoad %uint %i
+         %77 = OpAccessChain %_ptr_Function_S %var_for_index %75
+         %78 = OpLoad %S %77
+         %72 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %74 %78
+               OpBranch %61
+         %61 = OpLabel
+         %79 = OpLoad %uint %i
+         %80 = OpIAdd %uint %79 %uint_1
+               OpStore %i %80
+               OpBranch %59
+         %60 = OpLabel
+               OpReturn
+               OpFunctionEnd
+     %conv_S = OpFunction %S None %81
         %val = OpFunctionParameter %S_std140
-         %71 = OpLabel
-         %72 = OpCompositeExtract %int %val 0
-         %73 = OpCompositeExtract %v3half %val 1
-         %74 = OpCompositeExtract %v3half %val 2
-         %75 = OpCompositeConstruct %mat2v3half %73 %74
-         %76 = OpCompositeExtract %int %val 3
-         %77 = OpCompositeConstruct %S %72 %75 %76
-               OpReturnValue %77
-               OpFunctionEnd
-%conv_arr4_S = OpFunction %_arr_S_uint_4 None %78
-      %val_0 = OpFunctionParameter %_arr_S_std140_uint_4
-         %81 = OpLabel
-        %arr = OpVariable %_ptr_Function__arr_S_uint_4 Function %58
-        %i_0 = OpVariable %_ptr_Function_uint Function %43
-%var_for_index_1 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function %95
-               OpBranch %84
          %84 = OpLabel
-               OpLoopMerge %85 %86 None
-               OpBranch %87
-         %87 = OpLabel
-         %89 = OpLoad %uint %i_0
-         %90 = OpULessThan %bool %89 %uint_4
-         %88 = OpLogicalNot %bool %90
-               OpSelectionMerge %91 None
-               OpBranchConditional %88 %92 %91
-         %92 = OpLabel
-               OpBranch %85
-         %91 = OpLabel
+         %85 = OpCompositeExtract %int %val 0
+         %86 = OpCompositeExtract %v3half %val 1
+         %87 = OpCompositeExtract %v3half %val 2
+         %88 = OpCompositeConstruct %mat2v3half %86 %87
+         %89 = OpCompositeExtract %int %val 3
+         %90 = OpCompositeConstruct %S %85 %88 %89
+               OpReturnValue %90
+               OpFunctionEnd
+%conv_arr4_S = OpFunction %_arr_S_uint_4 None %91
+      %val_0 = OpFunctionParameter %_arr_S_std140_uint_4
+         %94 = OpLabel
+        %arr = OpVariable %_ptr_Function__arr_S_uint_4 Function %71
+        %i_0 = OpVariable %_ptr_Function_uint Function %30
+%var_for_index_1 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function %108
+               OpBranch %97
+         %97 = OpLabel
+               OpLoopMerge %98 %99 None
+               OpBranch %100
+        %100 = OpLabel
+        %102 = OpLoad %uint %i_0
+        %103 = OpULessThan %bool %102 %uint_4
+        %101 = OpLogicalNot %bool %103
+               OpSelectionMerge %104 None
+               OpBranchConditional %101 %105 %104
+        %105 = OpLabel
+               OpBranch %98
+        %104 = OpLabel
                OpStore %var_for_index_1 %val_0
-         %96 = OpLoad %uint %i_0
-         %97 = OpAccessChain %_ptr_Function_S %arr %96
-         %99 = OpLoad %uint %i_0
-        %101 = OpAccessChain %_ptr_Function_S_std140 %var_for_index_1 %99
-        %102 = OpLoad %S_std140 %101
-         %98 = OpFunctionCall %S %conv_S %102
-               OpStore %97 %98
-               OpBranch %86
-         %86 = OpLabel
-        %103 = OpLoad %uint %i_0
-        %104 = OpIAdd %uint %103 %uint_1
-               OpStore %i_0 %104
-               OpBranch %84
-         %85 = OpLabel
-        %105 = OpLoad %_arr_S_uint_4 %arr
-               OpReturnValue %105
+        %109 = OpLoad %uint %i_0
+        %110 = OpAccessChain %_ptr_Function_S %arr %109
+        %112 = OpLoad %uint %i_0
+        %114 = OpAccessChain %_ptr_Function_S_std140 %var_for_index_1 %112
+        %115 = OpLoad %S_std140 %114
+        %111 = OpFunctionCall %S %conv_S %115
+               OpStore %110 %111
+               OpBranch %99
+         %99 = OpLabel
+        %116 = OpLoad %uint %i_0
+        %117 = OpIAdd %uint %116 %uint_1
+               OpStore %i_0 %117
+               OpBranch %97
+         %98 = OpLabel
+        %118 = OpLoad %_arr_S_uint_4 %arr
+               OpReturnValue %118
                OpFunctionEnd
-%load_u_inner_2_m = OpFunction %mat2v3half None %106
-        %108 = OpLabel
-        %111 = OpAccessChain %_ptr_Uniform_S_std140 %u %uint_0 %uint_2
-        %114 = OpAccessChain %_ptr_Uniform_v3half %111 %uint_1
-        %115 = OpLoad %v3half %114
-        %117 = OpAccessChain %_ptr_Uniform_v3half %111 %uint_2
-        %118 = OpLoad %v3half %117
-        %119 = OpCompositeConstruct %mat2v3half %115 %118
-               OpReturnValue %119
+%load_u_inner_2_m = OpFunction %mat2v3half None %119
+        %121 = OpLabel
+        %124 = OpAccessChain %_ptr_Uniform_S_std140 %u %uint_0 %uint_2
+        %127 = OpAccessChain %_ptr_Uniform_v3half %124 %uint_1
+        %128 = OpLoad %v3half %127
+        %130 = OpAccessChain %_ptr_Uniform_v3half %124 %uint_2
+        %131 = OpLoad %v3half %130
+        %132 = OpCompositeConstruct %mat2v3half %128 %131
+               OpReturnValue %132
                OpFunctionEnd
-          %f = OpFunction %void None %120
-        %122 = OpLabel
-        %126 = OpAccessChain %_ptr_Uniform__arr_S_std140_uint_4 %u %uint_0
-        %127 = OpLoad %_arr_S_std140_uint_4 %126
-        %124 = OpFunctionCall %_arr_S_uint_4 %conv_arr4_S %127
-        %123 = OpFunctionCall %void %assign_and_preserve_padding_s %124
-        %131 = OpAccessChain %_ptr_Uniform_S_std140 %u %uint_0 %uint_2
-        %132 = OpLoad %S_std140 %131
-        %130 = OpFunctionCall %S %conv_S %132
-        %128 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %129 %130
-        %134 = OpAccessChain %_ptr_StorageBuffer_mat2v3half %s %uint_0 %int_3 %uint_1
-        %135 = OpFunctionCall %mat2v3half %load_u_inner_2_m
-               OpStore %134 %135
-        %138 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %int_1 %uint_1 %26
-        %139 = OpAccessChain %_ptr_Uniform_v3half %u %uint_0 %43 %uint_2
-        %140 = OpLoad %v3half %139
-        %141 = OpVectorShuffle %v3half %140 %140 2 0 1
-               OpStore %138 %141
+          %f = OpFunction %void None %133
+        %135 = OpLabel
+        %139 = OpAccessChain %_ptr_Uniform__arr_S_std140_uint_4 %u %uint_0
+        %140 = OpLoad %_arr_S_std140_uint_4 %139
+        %137 = OpFunctionCall %_arr_S_uint_4 %conv_arr4_S %140
+        %136 = OpFunctionCall %void %assign_and_preserve_padding_s %137
+        %144 = OpAccessChain %_ptr_Uniform_S_std140 %u %uint_0 %uint_2
+        %145 = OpLoad %S_std140 %144
+        %143 = OpFunctionCall %S %conv_S %145
+        %141 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %142 %143
+        %149 = OpFunctionCall %mat2v3half %load_u_inner_2_m
+        %146 = OpFunctionCall %void %assign_and_preserve_padding_2_s_X_m %148 %149
+        %150 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %int_1 %uint_1 %26
+        %151 = OpAccessChain %_ptr_Uniform_v3half %u %uint_0 %30 %uint_2
+        %152 = OpLoad %v3half %151
+        %153 = OpVectorShuffle %v3half %152 %152 2 0 1
+               OpStore %150 %153
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_storage.wgsl.expected.glsl
index 2c1183b..4f8d907 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_storage.wgsl.expected.glsl
@@ -36,26 +36,33 @@
   S inner[4];
 } s;
 
+void assign_and_preserve_padding_2_s_X_m(uint dest[1], mat2x3 value) {
+  s.inner[dest[0]].m[0] = value[0u];
+  s.inner[dest[0]].m[1] = value[1u];
+}
+
 void assign_and_preserve_padding_1_s_X(uint dest[1], S value) {
   s.inner[dest[0]].before = value.before;
-  s.inner[dest[0]].m = value.m;
+  uint tint_symbol[1] = uint[1](dest[0u]);
+  assign_and_preserve_padding_2_s_X_m(tint_symbol, value.m);
   s.inner[dest[0]].after = value.after;
 }
 
 void assign_and_preserve_padding_s(S value[4]) {
   {
     for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-      uint tint_symbol[1] = uint[1](i);
-      assign_and_preserve_padding_1_s_X(tint_symbol, value[i]);
+      uint tint_symbol_1[1] = uint[1](i);
+      assign_and_preserve_padding_1_s_X(tint_symbol_1, value[i]);
     }
   }
 }
 
 void f() {
   assign_and_preserve_padding_s(u.inner);
-  uint tint_symbol_1[1] = uint[1](1u);
-  assign_and_preserve_padding_1_s_X(tint_symbol_1, u.inner[2]);
-  s.inner[3].m = u.inner[2].m;
+  uint tint_symbol_2[1] = uint[1](1u);
+  assign_and_preserve_padding_1_s_X(tint_symbol_2, u.inner[2]);
+  uint tint_symbol_3[1] = uint[1](3u);
+  assign_and_preserve_padding_2_s_X_m(tint_symbol_3, u.inner[2].m);
   s.inner[1].m[0] = u.inner[0].m[1].zxy;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_storage.wgsl.expected.msl
index e6e4625..07e0d6b 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_storage.wgsl.expected.msl
@@ -23,9 +23,14 @@
   /* 0x0044 */ tint_array<int8_t, 60> tint_pad_2;
 };
 
+void assign_and_preserve_padding_2(device float2x3* const dest, float2x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+}
+
 void assign_and_preserve_padding_1(device S* const dest, S value) {
   (*(dest)).before = value.before;
-  (*(dest)).m = value.m;
+  assign_and_preserve_padding_2(&((*(dest)).m), value.m);
   (*(dest)).after = value.after;
 }
 
@@ -38,7 +43,7 @@
 kernel void f(device tint_array<S, 4>* tint_symbol [[buffer(1)]], const constant tint_array<S, 4>* tint_symbol_1 [[buffer(0)]]) {
   assign_and_preserve_padding(tint_symbol, *(tint_symbol_1));
   assign_and_preserve_padding_1(&((*(tint_symbol))[1]), (*(tint_symbol_1))[2]);
-  (*(tint_symbol))[3].m = (*(tint_symbol_1))[2].m;
+  assign_and_preserve_padding_2(&((*(tint_symbol))[3].m), (*(tint_symbol_1))[2].m);
   (*(tint_symbol))[1].m[0] = float3((*(tint_symbol_1))[0].m[1]).zxy;
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_storage.wgsl.expected.spvasm
index 02f84af..0835ddb 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 90
+; Bound: 102
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -15,11 +15,14 @@
                OpMemberName %S 2 "after"
                OpName %u "u"
                OpName %s "s"
-               OpName %assign_and_preserve_padding_1_s_X "assign_and_preserve_padding_1_s_X"
+               OpName %assign_and_preserve_padding_2_s_X_m "assign_and_preserve_padding_2_s_X_m"
                OpName %dest "dest"
                OpName %value "value"
-               OpName %assign_and_preserve_padding_s "assign_and_preserve_padding_s"
+               OpName %assign_and_preserve_padding_1_s_X "assign_and_preserve_padding_1_s_X"
+               OpName %dest_0 "dest"
                OpName %value_0 "value"
+               OpName %assign_and_preserve_padding_s "assign_and_preserve_padding_s"
+               OpName %value_1 "value"
                OpName %i "i"
                OpName %var_for_index "var_for_index"
                OpName %f "f"
@@ -53,98 +56,112 @@
        %void = OpTypeVoid
      %uint_1 = OpConstant %uint 1
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
-         %14 = OpTypeFunction %void %_arr_uint_uint_1 %S
+         %14 = OpTypeFunction %void %_arr_uint_uint_1 %mat2v3float
      %uint_0 = OpConstant %uint 0
          %23 = OpConstantNull %int
+%_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
+         %27 = OpConstantNull %uint
+      %int_1 = OpConstant %int 1
+         %33 = OpTypeFunction %void %_arr_uint_uint_1 %S
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-%_ptr_StorageBuffer_mat2v3float = OpTypePointer StorageBuffer %mat2v3float
      %uint_2 = OpConstant %uint 2
-         %36 = OpTypeFunction %void %_arr_S_uint_4
-         %40 = OpConstantNull %uint
+         %50 = OpTypeFunction %void %_arr_S_uint_4
 %_ptr_Function_uint = OpTypePointer Function %uint
        %bool = OpTypeBool
 %_ptr_Function__arr_S_uint_4 = OpTypePointer Function %_arr_S_uint_4
-         %55 = OpConstantNull %_arr_S_uint_4
+         %68 = OpConstantNull %_arr_S_uint_4
 %_ptr_Function_S = OpTypePointer Function %S
-         %65 = OpTypeFunction %void
+         %78 = OpTypeFunction %void
 %_ptr_Uniform__arr_S_uint_4 = OpTypePointer Uniform %_arr_S_uint_4
-         %73 = OpConstantComposite %_arr_uint_uint_1 %uint_1
+         %86 = OpConstantComposite %_arr_uint_uint_1 %uint_1
       %int_2 = OpConstant %int 2
 %_ptr_Uniform_S = OpTypePointer Uniform %S
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
+         %93 = OpConstantComposite %_arr_uint_uint_1 %uint_3
 %_ptr_Uniform_mat2v3float = OpTypePointer Uniform %mat2v3float
-      %int_1 = OpConstant %int 1
-%_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
-%assign_and_preserve_padding_1_s_X = OpFunction %void None %14
+%assign_and_preserve_padding_2_s_X_m = OpFunction %void None %14
        %dest = OpFunctionParameter %_arr_uint_uint_1
-      %value = OpFunctionParameter %S
+      %value = OpFunctionParameter %mat2v3float
          %21 = OpLabel
          %24 = OpCompositeExtract %uint %dest 0
-         %26 = OpAccessChain %_ptr_StorageBuffer_int %s %uint_0 %24 %uint_0
-         %27 = OpCompositeExtract %int %value 0
-               OpStore %26 %27
-         %28 = OpCompositeExtract %uint %dest 0
-         %30 = OpAccessChain %_ptr_StorageBuffer_mat2v3float %s %uint_0 %28 %uint_1
-         %31 = OpCompositeExtract %mat2v3float %value 1
-               OpStore %30 %31
-         %32 = OpCompositeExtract %uint %dest 0
-         %34 = OpAccessChain %_ptr_StorageBuffer_int %s %uint_0 %32 %uint_2
-         %35 = OpCompositeExtract %int %value 2
-               OpStore %34 %35
+         %26 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %24 %uint_1 %23
+         %28 = OpCompositeExtract %v3float %value 0
+               OpStore %26 %28
+         %29 = OpCompositeExtract %uint %dest 0
+         %31 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %29 %uint_1 %int_1
+         %32 = OpCompositeExtract %v3float %value 1
+               OpStore %31 %32
                OpReturn
                OpFunctionEnd
-%assign_and_preserve_padding_s = OpFunction %void None %36
-    %value_0 = OpFunctionParameter %_arr_S_uint_4
-         %39 = OpLabel
-          %i = OpVariable %_ptr_Function_uint Function %40
-%var_for_index = OpVariable %_ptr_Function__arr_S_uint_4 Function %55
-               OpStore %i %40
-               OpBranch %43
-         %43 = OpLabel
-               OpLoopMerge %44 %45 None
-               OpBranch %46
-         %46 = OpLabel
-         %48 = OpLoad %uint %i
-         %49 = OpULessThan %bool %48 %uint_4
-         %47 = OpLogicalNot %bool %49
-               OpSelectionMerge %51 None
-               OpBranchConditional %47 %52 %51
-         %52 = OpLabel
-               OpBranch %44
-         %51 = OpLabel
-               OpStore %var_for_index %value_0
-         %57 = OpLoad %uint %i
-         %58 = OpCompositeConstruct %_arr_uint_uint_1 %57
-         %59 = OpLoad %uint %i
-         %61 = OpAccessChain %_ptr_Function_S %var_for_index %59
-         %62 = OpLoad %S %61
-         %56 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %58 %62
-               OpBranch %45
-         %45 = OpLabel
-         %63 = OpLoad %uint %i
-         %64 = OpIAdd %uint %63 %uint_1
-               OpStore %i %64
-               OpBranch %43
-         %44 = OpLabel
+%assign_and_preserve_padding_1_s_X = OpFunction %void None %33
+     %dest_0 = OpFunctionParameter %_arr_uint_uint_1
+    %value_0 = OpFunctionParameter %S
+         %37 = OpLabel
+         %38 = OpCompositeExtract %uint %dest_0 0
+         %40 = OpAccessChain %_ptr_StorageBuffer_int %s %uint_0 %38 %uint_0
+         %41 = OpCompositeExtract %int %value_0 0
+               OpStore %40 %41
+         %43 = OpCompositeExtract %uint %dest_0 0
+         %44 = OpCompositeConstruct %_arr_uint_uint_1 %43
+         %45 = OpCompositeExtract %mat2v3float %value_0 1
+         %42 = OpFunctionCall %void %assign_and_preserve_padding_2_s_X_m %44 %45
+         %46 = OpCompositeExtract %uint %dest_0 0
+         %48 = OpAccessChain %_ptr_StorageBuffer_int %s %uint_0 %46 %uint_2
+         %49 = OpCompositeExtract %int %value_0 2
+               OpStore %48 %49
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %65
-         %67 = OpLabel
-         %70 = OpAccessChain %_ptr_Uniform__arr_S_uint_4 %u %uint_0
-         %71 = OpLoad %_arr_S_uint_4 %70
-         %68 = OpFunctionCall %void %assign_and_preserve_padding_s %71
-         %76 = OpAccessChain %_ptr_Uniform_S %u %uint_0 %int_2
-         %77 = OpLoad %S %76
-         %72 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %73 %77
-         %79 = OpAccessChain %_ptr_StorageBuffer_mat2v3float %s %uint_0 %int_3 %uint_1
-         %81 = OpAccessChain %_ptr_Uniform_mat2v3float %u %uint_0 %int_2 %uint_1
-         %82 = OpLoad %mat2v3float %81
-               OpStore %79 %82
-         %85 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %int_1 %uint_1 %23
-         %87 = OpAccessChain %_ptr_Uniform_v3float %u %uint_0 %23 %uint_1 %int_1
-         %88 = OpLoad %v3float %87
-         %89 = OpVectorShuffle %v3float %88 %88 2 0 1
-               OpStore %85 %89
+%assign_and_preserve_padding_s = OpFunction %void None %50
+    %value_1 = OpFunctionParameter %_arr_S_uint_4
+         %53 = OpLabel
+          %i = OpVariable %_ptr_Function_uint Function %27
+%var_for_index = OpVariable %_ptr_Function__arr_S_uint_4 Function %68
+               OpStore %i %27
+               OpBranch %56
+         %56 = OpLabel
+               OpLoopMerge %57 %58 None
+               OpBranch %59
+         %59 = OpLabel
+         %61 = OpLoad %uint %i
+         %62 = OpULessThan %bool %61 %uint_4
+         %60 = OpLogicalNot %bool %62
+               OpSelectionMerge %64 None
+               OpBranchConditional %60 %65 %64
+         %65 = OpLabel
+               OpBranch %57
+         %64 = OpLabel
+               OpStore %var_for_index %value_1
+         %70 = OpLoad %uint %i
+         %71 = OpCompositeConstruct %_arr_uint_uint_1 %70
+         %72 = OpLoad %uint %i
+         %74 = OpAccessChain %_ptr_Function_S %var_for_index %72
+         %75 = OpLoad %S %74
+         %69 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %71 %75
+               OpBranch %58
+         %58 = OpLabel
+         %76 = OpLoad %uint %i
+         %77 = OpIAdd %uint %76 %uint_1
+               OpStore %i %77
+               OpBranch %56
+         %57 = OpLabel
+               OpReturn
+               OpFunctionEnd
+          %f = OpFunction %void None %78
+         %80 = OpLabel
+         %83 = OpAccessChain %_ptr_Uniform__arr_S_uint_4 %u %uint_0
+         %84 = OpLoad %_arr_S_uint_4 %83
+         %81 = OpFunctionCall %void %assign_and_preserve_padding_s %84
+         %89 = OpAccessChain %_ptr_Uniform_S %u %uint_0 %int_2
+         %90 = OpLoad %S %89
+         %85 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %86 %90
+         %95 = OpAccessChain %_ptr_Uniform_mat2v3float %u %uint_0 %int_2 %uint_1
+         %96 = OpLoad %mat2v3float %95
+         %91 = OpFunctionCall %void %assign_and_preserve_padding_2_s_X_m %93 %96
+         %97 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %int_1 %uint_1 %23
+         %99 = OpAccessChain %_ptr_Uniform_v3float %u %uint_0 %23 %uint_1 %int_1
+        %100 = OpLoad %v3float %99
+        %101 = OpVectorShuffle %v3float %100 %100 2 0 1
+               OpStore %97 %101
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_storage.wgsl.expected.glsl
index bb31740..bb33893 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_storage.wgsl.expected.glsl
@@ -71,17 +71,24 @@
   S inner[4];
 } s;
 
+void assign_and_preserve_padding_2_s_X_m(uint dest[1], f16mat3 value) {
+  s.inner[dest[0]].m[0] = value[0u];
+  s.inner[dest[0]].m[1] = value[1u];
+  s.inner[dest[0]].m[2] = value[2u];
+}
+
 void assign_and_preserve_padding_1_s_X(uint dest[1], S value) {
   s.inner[dest[0]].before = value.before;
-  s.inner[dest[0]].m = value.m;
+  uint tint_symbol[1] = uint[1](dest[0u]);
+  assign_and_preserve_padding_2_s_X_m(tint_symbol, value.m);
   s.inner[dest[0]].after = value.after;
 }
 
 void assign_and_preserve_padding_s(S value[4]) {
   {
     for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-      uint tint_symbol[1] = uint[1](i);
-      assign_and_preserve_padding_1_s_X(tint_symbol, value[i]);
+      uint tint_symbol_1[1] = uint[1](i);
+      assign_and_preserve_padding_1_s_X(tint_symbol_1, value[i]);
     }
   }
 }
@@ -106,9 +113,10 @@
 
 void f() {
   assign_and_preserve_padding_s(conv_arr4_S(u.inner));
-  uint tint_symbol_1[1] = uint[1](1u);
-  assign_and_preserve_padding_1_s_X(tint_symbol_1, conv_S(u.inner[2u]));
-  s.inner[3].m = load_u_inner_2_m();
+  uint tint_symbol_2[1] = uint[1](1u);
+  assign_and_preserve_padding_1_s_X(tint_symbol_2, conv_S(u.inner[2u]));
+  uint tint_symbol_3[1] = uint[1](3u);
+  assign_and_preserve_padding_2_s_X_m(tint_symbol_3, load_u_inner_2_m());
   s.inner[1].m[0] = u.inner[0u].m_1.zxy;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_storage.wgsl.expected.msl
index 073f32d..bd652de 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_storage.wgsl.expected.msl
@@ -23,9 +23,15 @@
   /* 0x0044 */ tint_array<int8_t, 60> tint_pad_2;
 };
 
+void assign_and_preserve_padding_2(device half3x3* const dest, half3x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+}
+
 void assign_and_preserve_padding_1(device S* const dest, S value) {
   (*(dest)).before = value.before;
-  (*(dest)).m = value.m;
+  assign_and_preserve_padding_2(&((*(dest)).m), value.m);
   (*(dest)).after = value.after;
 }
 
@@ -38,7 +44,7 @@
 kernel void f(device tint_array<S, 4>* tint_symbol [[buffer(1)]], const constant tint_array<S, 4>* tint_symbol_1 [[buffer(0)]]) {
   assign_and_preserve_padding(tint_symbol, *(tint_symbol_1));
   assign_and_preserve_padding_1(&((*(tint_symbol))[1]), (*(tint_symbol_1))[2]);
-  (*(tint_symbol))[3].m = (*(tint_symbol_1))[2].m;
+  assign_and_preserve_padding_2(&((*(tint_symbol))[3].m), (*(tint_symbol_1))[2].m);
   (*(tint_symbol))[1].m[0] = half3((*(tint_symbol_1))[0].m[1]).zxy;
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_storage.wgsl.expected.spvasm
index 9355fa5..f81f539 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 147
+; Bound: 162
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -27,11 +27,14 @@
                OpMemberName %S 1 "m"
                OpMemberName %S 2 "after"
                OpName %s "s"
-               OpName %assign_and_preserve_padding_1_s_X "assign_and_preserve_padding_1_s_X"
+               OpName %assign_and_preserve_padding_2_s_X_m "assign_and_preserve_padding_2_s_X_m"
                OpName %dest "dest"
                OpName %value "value"
-               OpName %assign_and_preserve_padding_s "assign_and_preserve_padding_s"
+               OpName %assign_and_preserve_padding_1_s_X "assign_and_preserve_padding_1_s_X"
+               OpName %dest_0 "dest"
                OpName %value_0 "value"
+               OpName %assign_and_preserve_padding_s "assign_and_preserve_padding_s"
+               OpName %value_1 "value"
                OpName %i "i"
                OpName %var_for_index "var_for_index"
                OpName %conv_S "conv_S"
@@ -84,165 +87,183 @@
        %void = OpTypeVoid
      %uint_1 = OpConstant %uint 1
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
-         %17 = OpTypeFunction %void %_arr_uint_uint_1 %S
+         %17 = OpTypeFunction %void %_arr_uint_uint_1 %mat3v3half
      %uint_0 = OpConstant %uint 0
          %26 = OpConstantNull %int
-%_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-%_ptr_StorageBuffer_mat3v3half = OpTypePointer StorageBuffer %mat3v3half
+%_ptr_StorageBuffer_v3half = OpTypePointer StorageBuffer %v3half
+         %30 = OpConstantNull %uint
+      %int_1 = OpConstant %int 1
+      %int_2 = OpConstant %int 2
      %uint_2 = OpConstant %uint 2
-         %39 = OpTypeFunction %void %_arr_S_uint_4
-         %43 = OpConstantNull %uint
+         %41 = OpTypeFunction %void %_arr_uint_uint_1 %S
+%_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
+         %57 = OpTypeFunction %void %_arr_S_uint_4
 %_ptr_Function_uint = OpTypePointer Function %uint
        %bool = OpTypeBool
 %_ptr_Function__arr_S_uint_4 = OpTypePointer Function %_arr_S_uint_4
-         %58 = OpConstantNull %_arr_S_uint_4
+         %75 = OpConstantNull %_arr_S_uint_4
 %_ptr_Function_S = OpTypePointer Function %S
-         %68 = OpTypeFunction %S %S_std140
-         %79 = OpTypeFunction %_arr_S_uint_4 %_arr_S_std140_uint_4
+         %85 = OpTypeFunction %S %S_std140
+         %96 = OpTypeFunction %_arr_S_uint_4 %_arr_S_std140_uint_4
 %_ptr_Function__arr_S_std140_uint_4 = OpTypePointer Function %_arr_S_std140_uint_4
-         %96 = OpConstantNull %_arr_S_std140_uint_4
+        %113 = OpConstantNull %_arr_S_std140_uint_4
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
-        %107 = OpTypeFunction %mat3v3half
+        %124 = OpTypeFunction %mat3v3half
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
      %uint_3 = OpConstant %uint 3
-        %125 = OpTypeFunction %void
+        %142 = OpTypeFunction %void
 %_ptr_Uniform__arr_S_std140_uint_4 = OpTypePointer Uniform %_arr_S_std140_uint_4
-        %134 = OpConstantComposite %_arr_uint_uint_1 %uint_1
-      %int_3 = OpConstant %int 3
-      %int_1 = OpConstant %int 1
-%_ptr_StorageBuffer_v3half = OpTypePointer StorageBuffer %v3half
-%assign_and_preserve_padding_1_s_X = OpFunction %void None %17
+        %151 = OpConstantComposite %_arr_uint_uint_1 %uint_1
+        %156 = OpConstantComposite %_arr_uint_uint_1 %uint_3
+%assign_and_preserve_padding_2_s_X_m = OpFunction %void None %17
        %dest = OpFunctionParameter %_arr_uint_uint_1
-      %value = OpFunctionParameter %S
+      %value = OpFunctionParameter %mat3v3half
          %24 = OpLabel
          %27 = OpCompositeExtract %uint %dest 0
-         %29 = OpAccessChain %_ptr_StorageBuffer_int %s %uint_0 %27 %uint_0
-         %30 = OpCompositeExtract %int %value 0
-               OpStore %29 %30
-         %31 = OpCompositeExtract %uint %dest 0
-         %33 = OpAccessChain %_ptr_StorageBuffer_mat3v3half %s %uint_0 %31 %uint_1
-         %34 = OpCompositeExtract %mat3v3half %value 1
-               OpStore %33 %34
-         %35 = OpCompositeExtract %uint %dest 0
-         %37 = OpAccessChain %_ptr_StorageBuffer_int %s %uint_0 %35 %uint_2
-         %38 = OpCompositeExtract %int %value 2
-               OpStore %37 %38
+         %29 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %27 %uint_1 %26
+         %31 = OpCompositeExtract %v3half %value 0
+               OpStore %29 %31
+         %32 = OpCompositeExtract %uint %dest 0
+         %34 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %32 %uint_1 %int_1
+         %35 = OpCompositeExtract %v3half %value 1
+               OpStore %34 %35
+         %36 = OpCompositeExtract %uint %dest 0
+         %38 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %36 %uint_1 %int_2
+         %40 = OpCompositeExtract %v3half %value 2
+               OpStore %38 %40
                OpReturn
                OpFunctionEnd
-%assign_and_preserve_padding_s = OpFunction %void None %39
-    %value_0 = OpFunctionParameter %_arr_S_uint_4
-         %42 = OpLabel
-          %i = OpVariable %_ptr_Function_uint Function %43
-%var_for_index = OpVariable %_ptr_Function__arr_S_uint_4 Function %58
-               OpStore %i %43
-               OpBranch %46
-         %46 = OpLabel
-               OpLoopMerge %47 %48 None
-               OpBranch %49
-         %49 = OpLabel
-         %51 = OpLoad %uint %i
-         %52 = OpULessThan %bool %51 %uint_4
-         %50 = OpLogicalNot %bool %52
-               OpSelectionMerge %54 None
-               OpBranchConditional %50 %55 %54
-         %55 = OpLabel
-               OpBranch %47
-         %54 = OpLabel
-               OpStore %var_for_index %value_0
-         %60 = OpLoad %uint %i
-         %61 = OpCompositeConstruct %_arr_uint_uint_1 %60
-         %62 = OpLoad %uint %i
-         %64 = OpAccessChain %_ptr_Function_S %var_for_index %62
-         %65 = OpLoad %S %64
-         %59 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %61 %65
-               OpBranch %48
-         %48 = OpLabel
-         %66 = OpLoad %uint %i
-         %67 = OpIAdd %uint %66 %uint_1
-               OpStore %i %67
-               OpBranch %46
-         %47 = OpLabel
+%assign_and_preserve_padding_1_s_X = OpFunction %void None %41
+     %dest_0 = OpFunctionParameter %_arr_uint_uint_1
+    %value_0 = OpFunctionParameter %S
+         %45 = OpLabel
+         %46 = OpCompositeExtract %uint %dest_0 0
+         %48 = OpAccessChain %_ptr_StorageBuffer_int %s %uint_0 %46 %uint_0
+         %49 = OpCompositeExtract %int %value_0 0
+               OpStore %48 %49
+         %51 = OpCompositeExtract %uint %dest_0 0
+         %52 = OpCompositeConstruct %_arr_uint_uint_1 %51
+         %53 = OpCompositeExtract %mat3v3half %value_0 1
+         %50 = OpFunctionCall %void %assign_and_preserve_padding_2_s_X_m %52 %53
+         %54 = OpCompositeExtract %uint %dest_0 0
+         %55 = OpAccessChain %_ptr_StorageBuffer_int %s %uint_0 %54 %uint_2
+         %56 = OpCompositeExtract %int %value_0 2
+               OpStore %55 %56
                OpReturn
                OpFunctionEnd
-     %conv_S = OpFunction %S None %68
-        %val = OpFunctionParameter %S_std140
+%assign_and_preserve_padding_s = OpFunction %void None %57
+    %value_1 = OpFunctionParameter %_arr_S_uint_4
+         %60 = OpLabel
+          %i = OpVariable %_ptr_Function_uint Function %30
+%var_for_index = OpVariable %_ptr_Function__arr_S_uint_4 Function %75
+               OpStore %i %30
+               OpBranch %63
+         %63 = OpLabel
+               OpLoopMerge %64 %65 None
+               OpBranch %66
+         %66 = OpLabel
+         %68 = OpLoad %uint %i
+         %69 = OpULessThan %bool %68 %uint_4
+         %67 = OpLogicalNot %bool %69
+               OpSelectionMerge %71 None
+               OpBranchConditional %67 %72 %71
+         %72 = OpLabel
+               OpBranch %64
          %71 = OpLabel
-         %72 = OpCompositeExtract %int %val 0
-         %73 = OpCompositeExtract %v3half %val 1
-         %74 = OpCompositeExtract %v3half %val 2
-         %75 = OpCompositeExtract %v3half %val 3
-         %76 = OpCompositeConstruct %mat3v3half %73 %74 %75
-         %77 = OpCompositeExtract %int %val 4
-         %78 = OpCompositeConstruct %S %72 %76 %77
-               OpReturnValue %78
+               OpStore %var_for_index %value_1
+         %77 = OpLoad %uint %i
+         %78 = OpCompositeConstruct %_arr_uint_uint_1 %77
+         %79 = OpLoad %uint %i
+         %81 = OpAccessChain %_ptr_Function_S %var_for_index %79
+         %82 = OpLoad %S %81
+         %76 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %78 %82
+               OpBranch %65
+         %65 = OpLabel
+         %83 = OpLoad %uint %i
+         %84 = OpIAdd %uint %83 %uint_1
+               OpStore %i %84
+               OpBranch %63
+         %64 = OpLabel
+               OpReturn
                OpFunctionEnd
-%conv_arr4_S = OpFunction %_arr_S_uint_4 None %79
-      %val_0 = OpFunctionParameter %_arr_S_std140_uint_4
-         %82 = OpLabel
-        %arr = OpVariable %_ptr_Function__arr_S_uint_4 Function %58
-        %i_0 = OpVariable %_ptr_Function_uint Function %43
-%var_for_index_1 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function %96
-               OpBranch %85
-         %85 = OpLabel
-               OpLoopMerge %86 %87 None
-               OpBranch %88
+     %conv_S = OpFunction %S None %85
+        %val = OpFunctionParameter %S_std140
          %88 = OpLabel
-         %90 = OpLoad %uint %i_0
-         %91 = OpULessThan %bool %90 %uint_4
-         %89 = OpLogicalNot %bool %91
-               OpSelectionMerge %92 None
-               OpBranchConditional %89 %93 %92
-         %93 = OpLabel
-               OpBranch %86
-         %92 = OpLabel
-               OpStore %var_for_index_1 %val_0
-         %97 = OpLoad %uint %i_0
-         %98 = OpAccessChain %_ptr_Function_S %arr %97
-        %100 = OpLoad %uint %i_0
-        %102 = OpAccessChain %_ptr_Function_S_std140 %var_for_index_1 %100
-        %103 = OpLoad %S_std140 %102
-         %99 = OpFunctionCall %S %conv_S %103
-               OpStore %98 %99
-               OpBranch %87
-         %87 = OpLabel
-        %104 = OpLoad %uint %i_0
-        %105 = OpIAdd %uint %104 %uint_1
-               OpStore %i_0 %105
-               OpBranch %85
-         %86 = OpLabel
-        %106 = OpLoad %_arr_S_uint_4 %arr
-               OpReturnValue %106
+         %89 = OpCompositeExtract %int %val 0
+         %90 = OpCompositeExtract %v3half %val 1
+         %91 = OpCompositeExtract %v3half %val 2
+         %92 = OpCompositeExtract %v3half %val 3
+         %93 = OpCompositeConstruct %mat3v3half %90 %91 %92
+         %94 = OpCompositeExtract %int %val 4
+         %95 = OpCompositeConstruct %S %89 %93 %94
+               OpReturnValue %95
                OpFunctionEnd
-%load_u_inner_2_m = OpFunction %mat3v3half None %107
+%conv_arr4_S = OpFunction %_arr_S_uint_4 None %96
+      %val_0 = OpFunctionParameter %_arr_S_std140_uint_4
+         %99 = OpLabel
+        %arr = OpVariable %_ptr_Function__arr_S_uint_4 Function %75
+        %i_0 = OpVariable %_ptr_Function_uint Function %30
+%var_for_index_1 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function %113
+               OpBranch %102
+        %102 = OpLabel
+               OpLoopMerge %103 %104 None
+               OpBranch %105
+        %105 = OpLabel
+        %107 = OpLoad %uint %i_0
+        %108 = OpULessThan %bool %107 %uint_4
+        %106 = OpLogicalNot %bool %108
+               OpSelectionMerge %109 None
+               OpBranchConditional %106 %110 %109
+        %110 = OpLabel
+               OpBranch %103
         %109 = OpLabel
-        %112 = OpAccessChain %_ptr_Uniform_S_std140 %u %uint_0 %uint_2
-        %115 = OpAccessChain %_ptr_Uniform_v3half %112 %uint_1
-        %116 = OpLoad %v3half %115
-        %118 = OpAccessChain %_ptr_Uniform_v3half %112 %uint_2
-        %119 = OpLoad %v3half %118
-        %122 = OpAccessChain %_ptr_Uniform_v3half %112 %uint_3
-        %123 = OpLoad %v3half %122
-        %124 = OpCompositeConstruct %mat3v3half %116 %119 %123
-               OpReturnValue %124
+               OpStore %var_for_index_1 %val_0
+        %114 = OpLoad %uint %i_0
+        %115 = OpAccessChain %_ptr_Function_S %arr %114
+        %117 = OpLoad %uint %i_0
+        %119 = OpAccessChain %_ptr_Function_S_std140 %var_for_index_1 %117
+        %120 = OpLoad %S_std140 %119
+        %116 = OpFunctionCall %S %conv_S %120
+               OpStore %115 %116
+               OpBranch %104
+        %104 = OpLabel
+        %121 = OpLoad %uint %i_0
+        %122 = OpIAdd %uint %121 %uint_1
+               OpStore %i_0 %122
+               OpBranch %102
+        %103 = OpLabel
+        %123 = OpLoad %_arr_S_uint_4 %arr
+               OpReturnValue %123
                OpFunctionEnd
-          %f = OpFunction %void None %125
-        %127 = OpLabel
-        %131 = OpAccessChain %_ptr_Uniform__arr_S_std140_uint_4 %u %uint_0
-        %132 = OpLoad %_arr_S_std140_uint_4 %131
-        %129 = OpFunctionCall %_arr_S_uint_4 %conv_arr4_S %132
-        %128 = OpFunctionCall %void %assign_and_preserve_padding_s %129
-        %136 = OpAccessChain %_ptr_Uniform_S_std140 %u %uint_0 %uint_2
-        %137 = OpLoad %S_std140 %136
-        %135 = OpFunctionCall %S %conv_S %137
-        %133 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %134 %135
-        %139 = OpAccessChain %_ptr_StorageBuffer_mat3v3half %s %uint_0 %int_3 %uint_1
-        %140 = OpFunctionCall %mat3v3half %load_u_inner_2_m
-               OpStore %139 %140
-        %143 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %int_1 %uint_1 %26
-        %144 = OpAccessChain %_ptr_Uniform_v3half %u %uint_0 %43 %uint_2
-        %145 = OpLoad %v3half %144
-        %146 = OpVectorShuffle %v3half %145 %145 2 0 1
-               OpStore %143 %146
+%load_u_inner_2_m = OpFunction %mat3v3half None %124
+        %126 = OpLabel
+        %129 = OpAccessChain %_ptr_Uniform_S_std140 %u %uint_0 %uint_2
+        %132 = OpAccessChain %_ptr_Uniform_v3half %129 %uint_1
+        %133 = OpLoad %v3half %132
+        %135 = OpAccessChain %_ptr_Uniform_v3half %129 %uint_2
+        %136 = OpLoad %v3half %135
+        %139 = OpAccessChain %_ptr_Uniform_v3half %129 %uint_3
+        %140 = OpLoad %v3half %139
+        %141 = OpCompositeConstruct %mat3v3half %133 %136 %140
+               OpReturnValue %141
+               OpFunctionEnd
+          %f = OpFunction %void None %142
+        %144 = OpLabel
+        %148 = OpAccessChain %_ptr_Uniform__arr_S_std140_uint_4 %u %uint_0
+        %149 = OpLoad %_arr_S_std140_uint_4 %148
+        %146 = OpFunctionCall %_arr_S_uint_4 %conv_arr4_S %149
+        %145 = OpFunctionCall %void %assign_and_preserve_padding_s %146
+        %153 = OpAccessChain %_ptr_Uniform_S_std140 %u %uint_0 %uint_2
+        %154 = OpLoad %S_std140 %153
+        %152 = OpFunctionCall %S %conv_S %154
+        %150 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %151 %152
+        %157 = OpFunctionCall %mat3v3half %load_u_inner_2_m
+        %155 = OpFunctionCall %void %assign_and_preserve_padding_2_s_X_m %156 %157
+        %158 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %int_1 %uint_1 %26
+        %159 = OpAccessChain %_ptr_Uniform_v3half %u %uint_0 %30 %uint_2
+        %160 = OpLoad %v3half %159
+        %161 = OpVectorShuffle %v3half %160 %160 2 0 1
+               OpStore %158 %161
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_storage.wgsl.expected.glsl
index 9a055b8..6bb734d 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_storage.wgsl.expected.glsl
@@ -32,26 +32,34 @@
   S inner[4];
 } s;
 
+void assign_and_preserve_padding_2_s_X_m(uint dest[1], mat3 value) {
+  s.inner[dest[0]].m[0] = value[0u];
+  s.inner[dest[0]].m[1] = value[1u];
+  s.inner[dest[0]].m[2] = value[2u];
+}
+
 void assign_and_preserve_padding_1_s_X(uint dest[1], S value) {
   s.inner[dest[0]].before = value.before;
-  s.inner[dest[0]].m = value.m;
+  uint tint_symbol[1] = uint[1](dest[0u]);
+  assign_and_preserve_padding_2_s_X_m(tint_symbol, value.m);
   s.inner[dest[0]].after = value.after;
 }
 
 void assign_and_preserve_padding_s(S value[4]) {
   {
     for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-      uint tint_symbol[1] = uint[1](i);
-      assign_and_preserve_padding_1_s_X(tint_symbol, value[i]);
+      uint tint_symbol_1[1] = uint[1](i);
+      assign_and_preserve_padding_1_s_X(tint_symbol_1, value[i]);
     }
   }
 }
 
 void f() {
   assign_and_preserve_padding_s(u.inner);
-  uint tint_symbol_1[1] = uint[1](1u);
-  assign_and_preserve_padding_1_s_X(tint_symbol_1, u.inner[2]);
-  s.inner[3].m = u.inner[2].m;
+  uint tint_symbol_2[1] = uint[1](1u);
+  assign_and_preserve_padding_1_s_X(tint_symbol_2, u.inner[2]);
+  uint tint_symbol_3[1] = uint[1](3u);
+  assign_and_preserve_padding_2_s_X_m(tint_symbol_3, u.inner[2].m);
   s.inner[1].m[0] = u.inner[0].m[1].zxy;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_storage.wgsl.expected.msl
index a8ef11f..dc53f2a 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_storage.wgsl.expected.msl
@@ -22,9 +22,15 @@
   /* 0x0044 */ tint_array<int8_t, 60> tint_pad_1;
 };
 
+void assign_and_preserve_padding_2(device float3x3* const dest, float3x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+}
+
 void assign_and_preserve_padding_1(device S* const dest, S value) {
   (*(dest)).before = value.before;
-  (*(dest)).m = value.m;
+  assign_and_preserve_padding_2(&((*(dest)).m), value.m);
   (*(dest)).after = value.after;
 }
 
@@ -37,7 +43,7 @@
 kernel void f(device tint_array<S, 4>* tint_symbol [[buffer(1)]], const constant tint_array<S, 4>* tint_symbol_1 [[buffer(0)]]) {
   assign_and_preserve_padding(tint_symbol, *(tint_symbol_1));
   assign_and_preserve_padding_1(&((*(tint_symbol))[1]), (*(tint_symbol_1))[2]);
-  (*(tint_symbol))[3].m = (*(tint_symbol_1))[2].m;
+  assign_and_preserve_padding_2(&((*(tint_symbol))[3].m), (*(tint_symbol_1))[2].m);
   (*(tint_symbol))[1].m[0] = float3((*(tint_symbol_1))[0].m[1]).zxy;
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_storage.wgsl.expected.spvasm
index 68f6291..d6116a2 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 90
+; Bound: 105
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -15,11 +15,14 @@
                OpMemberName %S 2 "after"
                OpName %u "u"
                OpName %s "s"
-               OpName %assign_and_preserve_padding_1_s_X "assign_and_preserve_padding_1_s_X"
+               OpName %assign_and_preserve_padding_2_s_X_m "assign_and_preserve_padding_2_s_X_m"
                OpName %dest "dest"
                OpName %value "value"
-               OpName %assign_and_preserve_padding_s "assign_and_preserve_padding_s"
+               OpName %assign_and_preserve_padding_1_s_X "assign_and_preserve_padding_1_s_X"
+               OpName %dest_0 "dest"
                OpName %value_0 "value"
+               OpName %assign_and_preserve_padding_s "assign_and_preserve_padding_s"
+               OpName %value_1 "value"
                OpName %i "i"
                OpName %var_for_index "var_for_index"
                OpName %f "f"
@@ -53,98 +56,116 @@
        %void = OpTypeVoid
      %uint_1 = OpConstant %uint 1
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
-         %14 = OpTypeFunction %void %_arr_uint_uint_1 %S
+         %14 = OpTypeFunction %void %_arr_uint_uint_1 %mat3v3float
      %uint_0 = OpConstant %uint 0
          %23 = OpConstantNull %int
-%_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-%_ptr_StorageBuffer_mat3v3float = OpTypePointer StorageBuffer %mat3v3float
+%_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
+         %27 = OpConstantNull %uint
+      %int_1 = OpConstant %int 1
+      %int_2 = OpConstant %int 2
      %uint_2 = OpConstant %uint 2
-         %36 = OpTypeFunction %void %_arr_S_uint_4
-         %40 = OpConstantNull %uint
+         %38 = OpTypeFunction %void %_arr_uint_uint_1 %S
+%_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
+         %54 = OpTypeFunction %void %_arr_S_uint_4
 %_ptr_Function_uint = OpTypePointer Function %uint
        %bool = OpTypeBool
 %_ptr_Function__arr_S_uint_4 = OpTypePointer Function %_arr_S_uint_4
-         %55 = OpConstantNull %_arr_S_uint_4
+         %72 = OpConstantNull %_arr_S_uint_4
 %_ptr_Function_S = OpTypePointer Function %S
-         %65 = OpTypeFunction %void
+         %82 = OpTypeFunction %void
 %_ptr_Uniform__arr_S_uint_4 = OpTypePointer Uniform %_arr_S_uint_4
-         %73 = OpConstantComposite %_arr_uint_uint_1 %uint_1
-      %int_2 = OpConstant %int 2
+         %90 = OpConstantComposite %_arr_uint_uint_1 %uint_1
 %_ptr_Uniform_S = OpTypePointer Uniform %S
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
+         %96 = OpConstantComposite %_arr_uint_uint_1 %uint_3
 %_ptr_Uniform_mat3v3float = OpTypePointer Uniform %mat3v3float
-      %int_1 = OpConstant %int 1
-%_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
-%assign_and_preserve_padding_1_s_X = OpFunction %void None %14
+%assign_and_preserve_padding_2_s_X_m = OpFunction %void None %14
        %dest = OpFunctionParameter %_arr_uint_uint_1
-      %value = OpFunctionParameter %S
+      %value = OpFunctionParameter %mat3v3float
          %21 = OpLabel
          %24 = OpCompositeExtract %uint %dest 0
-         %26 = OpAccessChain %_ptr_StorageBuffer_int %s %uint_0 %24 %uint_0
-         %27 = OpCompositeExtract %int %value 0
-               OpStore %26 %27
-         %28 = OpCompositeExtract %uint %dest 0
-         %30 = OpAccessChain %_ptr_StorageBuffer_mat3v3float %s %uint_0 %28 %uint_1
-         %31 = OpCompositeExtract %mat3v3float %value 1
-               OpStore %30 %31
-         %32 = OpCompositeExtract %uint %dest 0
-         %34 = OpAccessChain %_ptr_StorageBuffer_int %s %uint_0 %32 %uint_2
-         %35 = OpCompositeExtract %int %value 2
-               OpStore %34 %35
+         %26 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %24 %uint_1 %23
+         %28 = OpCompositeExtract %v3float %value 0
+               OpStore %26 %28
+         %29 = OpCompositeExtract %uint %dest 0
+         %31 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %29 %uint_1 %int_1
+         %32 = OpCompositeExtract %v3float %value 1
+               OpStore %31 %32
+         %33 = OpCompositeExtract %uint %dest 0
+         %35 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %33 %uint_1 %int_2
+         %37 = OpCompositeExtract %v3float %value 2
+               OpStore %35 %37
                OpReturn
                OpFunctionEnd
-%assign_and_preserve_padding_s = OpFunction %void None %36
-    %value_0 = OpFunctionParameter %_arr_S_uint_4
-         %39 = OpLabel
-          %i = OpVariable %_ptr_Function_uint Function %40
-%var_for_index = OpVariable %_ptr_Function__arr_S_uint_4 Function %55
-               OpStore %i %40
-               OpBranch %43
-         %43 = OpLabel
-               OpLoopMerge %44 %45 None
-               OpBranch %46
-         %46 = OpLabel
-         %48 = OpLoad %uint %i
-         %49 = OpULessThan %bool %48 %uint_4
-         %47 = OpLogicalNot %bool %49
-               OpSelectionMerge %51 None
-               OpBranchConditional %47 %52 %51
-         %52 = OpLabel
-               OpBranch %44
-         %51 = OpLabel
-               OpStore %var_for_index %value_0
-         %57 = OpLoad %uint %i
-         %58 = OpCompositeConstruct %_arr_uint_uint_1 %57
-         %59 = OpLoad %uint %i
-         %61 = OpAccessChain %_ptr_Function_S %var_for_index %59
-         %62 = OpLoad %S %61
-         %56 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %58 %62
-               OpBranch %45
-         %45 = OpLabel
-         %63 = OpLoad %uint %i
-         %64 = OpIAdd %uint %63 %uint_1
-               OpStore %i %64
-               OpBranch %43
-         %44 = OpLabel
+%assign_and_preserve_padding_1_s_X = OpFunction %void None %38
+     %dest_0 = OpFunctionParameter %_arr_uint_uint_1
+    %value_0 = OpFunctionParameter %S
+         %42 = OpLabel
+         %43 = OpCompositeExtract %uint %dest_0 0
+         %45 = OpAccessChain %_ptr_StorageBuffer_int %s %uint_0 %43 %uint_0
+         %46 = OpCompositeExtract %int %value_0 0
+               OpStore %45 %46
+         %48 = OpCompositeExtract %uint %dest_0 0
+         %49 = OpCompositeConstruct %_arr_uint_uint_1 %48
+         %50 = OpCompositeExtract %mat3v3float %value_0 1
+         %47 = OpFunctionCall %void %assign_and_preserve_padding_2_s_X_m %49 %50
+         %51 = OpCompositeExtract %uint %dest_0 0
+         %52 = OpAccessChain %_ptr_StorageBuffer_int %s %uint_0 %51 %uint_2
+         %53 = OpCompositeExtract %int %value_0 2
+               OpStore %52 %53
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %65
-         %67 = OpLabel
-         %70 = OpAccessChain %_ptr_Uniform__arr_S_uint_4 %u %uint_0
-         %71 = OpLoad %_arr_S_uint_4 %70
-         %68 = OpFunctionCall %void %assign_and_preserve_padding_s %71
-         %76 = OpAccessChain %_ptr_Uniform_S %u %uint_0 %int_2
-         %77 = OpLoad %S %76
-         %72 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %73 %77
-         %79 = OpAccessChain %_ptr_StorageBuffer_mat3v3float %s %uint_0 %int_3 %uint_1
-         %81 = OpAccessChain %_ptr_Uniform_mat3v3float %u %uint_0 %int_2 %uint_1
-         %82 = OpLoad %mat3v3float %81
-               OpStore %79 %82
-         %85 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %int_1 %uint_1 %23
-         %87 = OpAccessChain %_ptr_Uniform_v3float %u %uint_0 %23 %uint_1 %int_1
-         %88 = OpLoad %v3float %87
-         %89 = OpVectorShuffle %v3float %88 %88 2 0 1
-               OpStore %85 %89
+%assign_and_preserve_padding_s = OpFunction %void None %54
+    %value_1 = OpFunctionParameter %_arr_S_uint_4
+         %57 = OpLabel
+          %i = OpVariable %_ptr_Function_uint Function %27
+%var_for_index = OpVariable %_ptr_Function__arr_S_uint_4 Function %72
+               OpStore %i %27
+               OpBranch %60
+         %60 = OpLabel
+               OpLoopMerge %61 %62 None
+               OpBranch %63
+         %63 = OpLabel
+         %65 = OpLoad %uint %i
+         %66 = OpULessThan %bool %65 %uint_4
+         %64 = OpLogicalNot %bool %66
+               OpSelectionMerge %68 None
+               OpBranchConditional %64 %69 %68
+         %69 = OpLabel
+               OpBranch %61
+         %68 = OpLabel
+               OpStore %var_for_index %value_1
+         %74 = OpLoad %uint %i
+         %75 = OpCompositeConstruct %_arr_uint_uint_1 %74
+         %76 = OpLoad %uint %i
+         %78 = OpAccessChain %_ptr_Function_S %var_for_index %76
+         %79 = OpLoad %S %78
+         %73 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %75 %79
+               OpBranch %62
+         %62 = OpLabel
+         %80 = OpLoad %uint %i
+         %81 = OpIAdd %uint %80 %uint_1
+               OpStore %i %81
+               OpBranch %60
+         %61 = OpLabel
+               OpReturn
+               OpFunctionEnd
+          %f = OpFunction %void None %82
+         %84 = OpLabel
+         %87 = OpAccessChain %_ptr_Uniform__arr_S_uint_4 %u %uint_0
+         %88 = OpLoad %_arr_S_uint_4 %87
+         %85 = OpFunctionCall %void %assign_and_preserve_padding_s %88
+         %92 = OpAccessChain %_ptr_Uniform_S %u %uint_0 %int_2
+         %93 = OpLoad %S %92
+         %89 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %90 %93
+         %98 = OpAccessChain %_ptr_Uniform_mat3v3float %u %uint_0 %int_2 %uint_1
+         %99 = OpLoad %mat3v3float %98
+         %94 = OpFunctionCall %void %assign_and_preserve_padding_2_s_X_m %96 %99
+        %100 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %int_1 %uint_1 %23
+        %102 = OpAccessChain %_ptr_Uniform_v3float %u %uint_0 %23 %uint_1 %int_1
+        %103 = OpLoad %v3float %102
+        %104 = OpVectorShuffle %v3float %103 %103 2 0 1
+               OpStore %100 %104
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_storage.wgsl.expected.glsl
index b35a2b4..c6b4a70 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_storage.wgsl.expected.glsl
@@ -68,17 +68,25 @@
   S inner[4];
 } s;
 
+void assign_and_preserve_padding_2_s_X_m(uint dest[1], f16mat4x3 value) {
+  s.inner[dest[0]].m[0] = value[0u];
+  s.inner[dest[0]].m[1] = value[1u];
+  s.inner[dest[0]].m[2] = value[2u];
+  s.inner[dest[0]].m[3] = value[3u];
+}
+
 void assign_and_preserve_padding_1_s_X(uint dest[1], S value) {
   s.inner[dest[0]].before = value.before;
-  s.inner[dest[0]].m = value.m;
+  uint tint_symbol[1] = uint[1](dest[0u]);
+  assign_and_preserve_padding_2_s_X_m(tint_symbol, value.m);
   s.inner[dest[0]].after = value.after;
 }
 
 void assign_and_preserve_padding_s(S value[4]) {
   {
     for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-      uint tint_symbol[1] = uint[1](i);
-      assign_and_preserve_padding_1_s_X(tint_symbol, value[i]);
+      uint tint_symbol_1[1] = uint[1](i);
+      assign_and_preserve_padding_1_s_X(tint_symbol_1, value[i]);
     }
   }
 }
@@ -103,9 +111,10 @@
 
 void f() {
   assign_and_preserve_padding_s(conv_arr4_S(u.inner));
-  uint tint_symbol_1[1] = uint[1](1u);
-  assign_and_preserve_padding_1_s_X(tint_symbol_1, conv_S(u.inner[2u]));
-  s.inner[3].m = load_u_inner_2_m();
+  uint tint_symbol_2[1] = uint[1](1u);
+  assign_and_preserve_padding_1_s_X(tint_symbol_2, conv_S(u.inner[2u]));
+  uint tint_symbol_3[1] = uint[1](3u);
+  assign_and_preserve_padding_2_s_X_m(tint_symbol_3, load_u_inner_2_m());
   s.inner[1].m[0] = u.inner[0u].m_1.zxy;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_storage.wgsl.expected.msl
index 4b99bff..448f2693 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_storage.wgsl.expected.msl
@@ -23,9 +23,16 @@
   /* 0x0044 */ tint_array<int8_t, 60> tint_pad_2;
 };
 
+void assign_and_preserve_padding_2(device half4x3* const dest, half4x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+  (*(dest))[3u] = value[3u];
+}
+
 void assign_and_preserve_padding_1(device S* const dest, S value) {
   (*(dest)).before = value.before;
-  (*(dest)).m = value.m;
+  assign_and_preserve_padding_2(&((*(dest)).m), value.m);
   (*(dest)).after = value.after;
 }
 
@@ -38,7 +45,7 @@
 kernel void f(device tint_array<S, 4>* tint_symbol [[buffer(1)]], const constant tint_array<S, 4>* tint_symbol_1 [[buffer(0)]]) {
   assign_and_preserve_padding(tint_symbol, *(tint_symbol_1));
   assign_and_preserve_padding_1(&((*(tint_symbol))[1]), (*(tint_symbol_1))[2]);
-  (*(tint_symbol))[3].m = (*(tint_symbol_1))[2].m;
+  assign_and_preserve_padding_2(&((*(tint_symbol))[3].m), (*(tint_symbol_1))[2].m);
   (*(tint_symbol))[1].m[0] = half3((*(tint_symbol_1))[0].m[1]).zxy;
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_storage.wgsl.expected.spvasm
index 41d2d0b..f92a2a1 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 151
+; Bound: 170
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -28,11 +28,14 @@
                OpMemberName %S 1 "m"
                OpMemberName %S 2 "after"
                OpName %s "s"
-               OpName %assign_and_preserve_padding_1_s_X "assign_and_preserve_padding_1_s_X"
+               OpName %assign_and_preserve_padding_2_s_X_m "assign_and_preserve_padding_2_s_X_m"
                OpName %dest "dest"
                OpName %value "value"
-               OpName %assign_and_preserve_padding_s "assign_and_preserve_padding_s"
+               OpName %assign_and_preserve_padding_1_s_X "assign_and_preserve_padding_1_s_X"
+               OpName %dest_0 "dest"
                OpName %value_0 "value"
+               OpName %assign_and_preserve_padding_s "assign_and_preserve_padding_s"
+               OpName %value_1 "value"
                OpName %i "i"
                OpName %var_for_index "var_for_index"
                OpName %conv_S "conv_S"
@@ -86,168 +89,191 @@
        %void = OpTypeVoid
      %uint_1 = OpConstant %uint 1
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
-         %17 = OpTypeFunction %void %_arr_uint_uint_1 %S
+         %17 = OpTypeFunction %void %_arr_uint_uint_1 %mat4v3half
      %uint_0 = OpConstant %uint 0
          %26 = OpConstantNull %int
-%_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-%_ptr_StorageBuffer_mat4v3half = OpTypePointer StorageBuffer %mat4v3half
+%_ptr_StorageBuffer_v3half = OpTypePointer StorageBuffer %v3half
+         %30 = OpConstantNull %uint
+      %int_1 = OpConstant %int 1
+      %int_2 = OpConstant %int 2
      %uint_2 = OpConstant %uint 2
-         %39 = OpTypeFunction %void %_arr_S_uint_4
-         %43 = OpConstantNull %uint
+      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
+         %46 = OpTypeFunction %void %_arr_uint_uint_1 %S
+%_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
+         %62 = OpTypeFunction %void %_arr_S_uint_4
 %_ptr_Function_uint = OpTypePointer Function %uint
        %bool = OpTypeBool
 %_ptr_Function__arr_S_uint_4 = OpTypePointer Function %_arr_S_uint_4
-         %58 = OpConstantNull %_arr_S_uint_4
+         %80 = OpConstantNull %_arr_S_uint_4
 %_ptr_Function_S = OpTypePointer Function %S
-         %68 = OpTypeFunction %S %S_std140
-         %80 = OpTypeFunction %_arr_S_uint_4 %_arr_S_std140_uint_4
+         %90 = OpTypeFunction %S %S_std140
+        %102 = OpTypeFunction %_arr_S_uint_4 %_arr_S_std140_uint_4
 %_ptr_Function__arr_S_std140_uint_4 = OpTypePointer Function %_arr_S_std140_uint_4
-         %97 = OpConstantNull %_arr_S_std140_uint_4
+        %119 = OpConstantNull %_arr_S_std140_uint_4
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
-        %108 = OpTypeFunction %mat4v3half
+        %130 = OpTypeFunction %mat4v3half
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
-     %uint_3 = OpConstant %uint 3
-        %129 = OpTypeFunction %void
+        %150 = OpTypeFunction %void
 %_ptr_Uniform__arr_S_std140_uint_4 = OpTypePointer Uniform %_arr_S_std140_uint_4
-        %138 = OpConstantComposite %_arr_uint_uint_1 %uint_1
-      %int_3 = OpConstant %int 3
-      %int_1 = OpConstant %int 1
-%_ptr_StorageBuffer_v3half = OpTypePointer StorageBuffer %v3half
-%assign_and_preserve_padding_1_s_X = OpFunction %void None %17
+        %159 = OpConstantComposite %_arr_uint_uint_1 %uint_1
+        %164 = OpConstantComposite %_arr_uint_uint_1 %uint_3
+%assign_and_preserve_padding_2_s_X_m = OpFunction %void None %17
        %dest = OpFunctionParameter %_arr_uint_uint_1
-      %value = OpFunctionParameter %S
+      %value = OpFunctionParameter %mat4v3half
          %24 = OpLabel
          %27 = OpCompositeExtract %uint %dest 0
-         %29 = OpAccessChain %_ptr_StorageBuffer_int %s %uint_0 %27 %uint_0
-         %30 = OpCompositeExtract %int %value 0
-               OpStore %29 %30
-         %31 = OpCompositeExtract %uint %dest 0
-         %33 = OpAccessChain %_ptr_StorageBuffer_mat4v3half %s %uint_0 %31 %uint_1
-         %34 = OpCompositeExtract %mat4v3half %value 1
-               OpStore %33 %34
-         %35 = OpCompositeExtract %uint %dest 0
-         %37 = OpAccessChain %_ptr_StorageBuffer_int %s %uint_0 %35 %uint_2
-         %38 = OpCompositeExtract %int %value 2
-               OpStore %37 %38
+         %29 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %27 %uint_1 %26
+         %31 = OpCompositeExtract %v3half %value 0
+               OpStore %29 %31
+         %32 = OpCompositeExtract %uint %dest 0
+         %34 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %32 %uint_1 %int_1
+         %35 = OpCompositeExtract %v3half %value 1
+               OpStore %34 %35
+         %36 = OpCompositeExtract %uint %dest 0
+         %38 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %36 %uint_1 %int_2
+         %40 = OpCompositeExtract %v3half %value 2
+               OpStore %38 %40
+         %41 = OpCompositeExtract %uint %dest 0
+         %43 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %41 %uint_1 %int_3
+         %45 = OpCompositeExtract %v3half %value 3
+               OpStore %43 %45
                OpReturn
                OpFunctionEnd
-%assign_and_preserve_padding_s = OpFunction %void None %39
-    %value_0 = OpFunctionParameter %_arr_S_uint_4
-         %42 = OpLabel
-          %i = OpVariable %_ptr_Function_uint Function %43
-%var_for_index = OpVariable %_ptr_Function__arr_S_uint_4 Function %58
-               OpStore %i %43
-               OpBranch %46
-         %46 = OpLabel
-               OpLoopMerge %47 %48 None
-               OpBranch %49
-         %49 = OpLabel
-         %51 = OpLoad %uint %i
-         %52 = OpULessThan %bool %51 %uint_4
-         %50 = OpLogicalNot %bool %52
-               OpSelectionMerge %54 None
-               OpBranchConditional %50 %55 %54
-         %55 = OpLabel
-               OpBranch %47
-         %54 = OpLabel
-               OpStore %var_for_index %value_0
-         %60 = OpLoad %uint %i
-         %61 = OpCompositeConstruct %_arr_uint_uint_1 %60
-         %62 = OpLoad %uint %i
-         %64 = OpAccessChain %_ptr_Function_S %var_for_index %62
-         %65 = OpLoad %S %64
-         %59 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %61 %65
-               OpBranch %48
-         %48 = OpLabel
-         %66 = OpLoad %uint %i
-         %67 = OpIAdd %uint %66 %uint_1
-               OpStore %i %67
-               OpBranch %46
-         %47 = OpLabel
+%assign_and_preserve_padding_1_s_X = OpFunction %void None %46
+     %dest_0 = OpFunctionParameter %_arr_uint_uint_1
+    %value_0 = OpFunctionParameter %S
+         %50 = OpLabel
+         %51 = OpCompositeExtract %uint %dest_0 0
+         %53 = OpAccessChain %_ptr_StorageBuffer_int %s %uint_0 %51 %uint_0
+         %54 = OpCompositeExtract %int %value_0 0
+               OpStore %53 %54
+         %56 = OpCompositeExtract %uint %dest_0 0
+         %57 = OpCompositeConstruct %_arr_uint_uint_1 %56
+         %58 = OpCompositeExtract %mat4v3half %value_0 1
+         %55 = OpFunctionCall %void %assign_and_preserve_padding_2_s_X_m %57 %58
+         %59 = OpCompositeExtract %uint %dest_0 0
+         %60 = OpAccessChain %_ptr_StorageBuffer_int %s %uint_0 %59 %uint_2
+         %61 = OpCompositeExtract %int %value_0 2
+               OpStore %60 %61
                OpReturn
                OpFunctionEnd
-     %conv_S = OpFunction %S None %68
-        %val = OpFunctionParameter %S_std140
+%assign_and_preserve_padding_s = OpFunction %void None %62
+    %value_1 = OpFunctionParameter %_arr_S_uint_4
+         %65 = OpLabel
+          %i = OpVariable %_ptr_Function_uint Function %30
+%var_for_index = OpVariable %_ptr_Function__arr_S_uint_4 Function %80
+               OpStore %i %30
+               OpBranch %68
+         %68 = OpLabel
+               OpLoopMerge %69 %70 None
+               OpBranch %71
          %71 = OpLabel
-         %72 = OpCompositeExtract %int %val 0
-         %73 = OpCompositeExtract %v3half %val 1
-         %74 = OpCompositeExtract %v3half %val 2
-         %75 = OpCompositeExtract %v3half %val 3
-         %76 = OpCompositeExtract %v3half %val 4
-         %77 = OpCompositeConstruct %mat4v3half %73 %74 %75 %76
-         %78 = OpCompositeExtract %int %val 5
-         %79 = OpCompositeConstruct %S %72 %77 %78
-               OpReturnValue %79
+         %73 = OpLoad %uint %i
+         %74 = OpULessThan %bool %73 %uint_4
+         %72 = OpLogicalNot %bool %74
+               OpSelectionMerge %76 None
+               OpBranchConditional %72 %77 %76
+         %77 = OpLabel
+               OpBranch %69
+         %76 = OpLabel
+               OpStore %var_for_index %value_1
+         %82 = OpLoad %uint %i
+         %83 = OpCompositeConstruct %_arr_uint_uint_1 %82
+         %84 = OpLoad %uint %i
+         %86 = OpAccessChain %_ptr_Function_S %var_for_index %84
+         %87 = OpLoad %S %86
+         %81 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %83 %87
+               OpBranch %70
+         %70 = OpLabel
+         %88 = OpLoad %uint %i
+         %89 = OpIAdd %uint %88 %uint_1
+               OpStore %i %89
+               OpBranch %68
+         %69 = OpLabel
+               OpReturn
                OpFunctionEnd
-%conv_arr4_S = OpFunction %_arr_S_uint_4 None %80
-      %val_0 = OpFunctionParameter %_arr_S_std140_uint_4
-         %83 = OpLabel
-        %arr = OpVariable %_ptr_Function__arr_S_uint_4 Function %58
-        %i_0 = OpVariable %_ptr_Function_uint Function %43
-%var_for_index_1 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function %97
-               OpBranch %86
-         %86 = OpLabel
-               OpLoopMerge %87 %88 None
-               OpBranch %89
-         %89 = OpLabel
-         %91 = OpLoad %uint %i_0
-         %92 = OpULessThan %bool %91 %uint_4
-         %90 = OpLogicalNot %bool %92
-               OpSelectionMerge %93 None
-               OpBranchConditional %90 %94 %93
-         %94 = OpLabel
-               OpBranch %87
+     %conv_S = OpFunction %S None %90
+        %val = OpFunctionParameter %S_std140
          %93 = OpLabel
+         %94 = OpCompositeExtract %int %val 0
+         %95 = OpCompositeExtract %v3half %val 1
+         %96 = OpCompositeExtract %v3half %val 2
+         %97 = OpCompositeExtract %v3half %val 3
+         %98 = OpCompositeExtract %v3half %val 4
+         %99 = OpCompositeConstruct %mat4v3half %95 %96 %97 %98
+        %100 = OpCompositeExtract %int %val 5
+        %101 = OpCompositeConstruct %S %94 %99 %100
+               OpReturnValue %101
+               OpFunctionEnd
+%conv_arr4_S = OpFunction %_arr_S_uint_4 None %102
+      %val_0 = OpFunctionParameter %_arr_S_std140_uint_4
+        %105 = OpLabel
+        %arr = OpVariable %_ptr_Function__arr_S_uint_4 Function %80
+        %i_0 = OpVariable %_ptr_Function_uint Function %30
+%var_for_index_1 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function %119
+               OpBranch %108
+        %108 = OpLabel
+               OpLoopMerge %109 %110 None
+               OpBranch %111
+        %111 = OpLabel
+        %113 = OpLoad %uint %i_0
+        %114 = OpULessThan %bool %113 %uint_4
+        %112 = OpLogicalNot %bool %114
+               OpSelectionMerge %115 None
+               OpBranchConditional %112 %116 %115
+        %116 = OpLabel
+               OpBranch %109
+        %115 = OpLabel
                OpStore %var_for_index_1 %val_0
-         %98 = OpLoad %uint %i_0
-         %99 = OpAccessChain %_ptr_Function_S %arr %98
-        %101 = OpLoad %uint %i_0
-        %103 = OpAccessChain %_ptr_Function_S_std140 %var_for_index_1 %101
-        %104 = OpLoad %S_std140 %103
-        %100 = OpFunctionCall %S %conv_S %104
-               OpStore %99 %100
-               OpBranch %88
-         %88 = OpLabel
-        %105 = OpLoad %uint %i_0
-        %106 = OpIAdd %uint %105 %uint_1
-               OpStore %i_0 %106
-               OpBranch %86
-         %87 = OpLabel
-        %107 = OpLoad %_arr_S_uint_4 %arr
-               OpReturnValue %107
-               OpFunctionEnd
-%load_u_inner_2_m = OpFunction %mat4v3half None %108
+        %120 = OpLoad %uint %i_0
+        %121 = OpAccessChain %_ptr_Function_S %arr %120
+        %123 = OpLoad %uint %i_0
+        %125 = OpAccessChain %_ptr_Function_S_std140 %var_for_index_1 %123
+        %126 = OpLoad %S_std140 %125
+        %122 = OpFunctionCall %S %conv_S %126
+               OpStore %121 %122
+               OpBranch %110
         %110 = OpLabel
-        %113 = OpAccessChain %_ptr_Uniform_S_std140 %u %uint_0 %uint_2
-        %116 = OpAccessChain %_ptr_Uniform_v3half %113 %uint_1
-        %117 = OpLoad %v3half %116
-        %119 = OpAccessChain %_ptr_Uniform_v3half %113 %uint_2
-        %120 = OpLoad %v3half %119
-        %123 = OpAccessChain %_ptr_Uniform_v3half %113 %uint_3
-        %124 = OpLoad %v3half %123
-        %126 = OpAccessChain %_ptr_Uniform_v3half %113 %uint_4
-        %127 = OpLoad %v3half %126
-        %128 = OpCompositeConstruct %mat4v3half %117 %120 %124 %127
-               OpReturnValue %128
+        %127 = OpLoad %uint %i_0
+        %128 = OpIAdd %uint %127 %uint_1
+               OpStore %i_0 %128
+               OpBranch %108
+        %109 = OpLabel
+        %129 = OpLoad %_arr_S_uint_4 %arr
+               OpReturnValue %129
                OpFunctionEnd
-          %f = OpFunction %void None %129
-        %131 = OpLabel
-        %135 = OpAccessChain %_ptr_Uniform__arr_S_std140_uint_4 %u %uint_0
-        %136 = OpLoad %_arr_S_std140_uint_4 %135
-        %133 = OpFunctionCall %_arr_S_uint_4 %conv_arr4_S %136
-        %132 = OpFunctionCall %void %assign_and_preserve_padding_s %133
-        %140 = OpAccessChain %_ptr_Uniform_S_std140 %u %uint_0 %uint_2
-        %141 = OpLoad %S_std140 %140
-        %139 = OpFunctionCall %S %conv_S %141
-        %137 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %138 %139
-        %143 = OpAccessChain %_ptr_StorageBuffer_mat4v3half %s %uint_0 %int_3 %uint_1
-        %144 = OpFunctionCall %mat4v3half %load_u_inner_2_m
-               OpStore %143 %144
-        %147 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %int_1 %uint_1 %26
-        %148 = OpAccessChain %_ptr_Uniform_v3half %u %uint_0 %43 %uint_2
-        %149 = OpLoad %v3half %148
-        %150 = OpVectorShuffle %v3half %149 %149 2 0 1
-               OpStore %147 %150
+%load_u_inner_2_m = OpFunction %mat4v3half None %130
+        %132 = OpLabel
+        %135 = OpAccessChain %_ptr_Uniform_S_std140 %u %uint_0 %uint_2
+        %138 = OpAccessChain %_ptr_Uniform_v3half %135 %uint_1
+        %139 = OpLoad %v3half %138
+        %141 = OpAccessChain %_ptr_Uniform_v3half %135 %uint_2
+        %142 = OpLoad %v3half %141
+        %144 = OpAccessChain %_ptr_Uniform_v3half %135 %uint_3
+        %145 = OpLoad %v3half %144
+        %147 = OpAccessChain %_ptr_Uniform_v3half %135 %uint_4
+        %148 = OpLoad %v3half %147
+        %149 = OpCompositeConstruct %mat4v3half %139 %142 %145 %148
+               OpReturnValue %149
+               OpFunctionEnd
+          %f = OpFunction %void None %150
+        %152 = OpLabel
+        %156 = OpAccessChain %_ptr_Uniform__arr_S_std140_uint_4 %u %uint_0
+        %157 = OpLoad %_arr_S_std140_uint_4 %156
+        %154 = OpFunctionCall %_arr_S_uint_4 %conv_arr4_S %157
+        %153 = OpFunctionCall %void %assign_and_preserve_padding_s %154
+        %161 = OpAccessChain %_ptr_Uniform_S_std140 %u %uint_0 %uint_2
+        %162 = OpLoad %S_std140 %161
+        %160 = OpFunctionCall %S %conv_S %162
+        %158 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %159 %160
+        %165 = OpFunctionCall %mat4v3half %load_u_inner_2_m
+        %163 = OpFunctionCall %void %assign_and_preserve_padding_2_s_X_m %164 %165
+        %166 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %int_1 %uint_1 %26
+        %167 = OpAccessChain %_ptr_Uniform_v3half %u %uint_0 %30 %uint_2
+        %168 = OpLoad %v3half %167
+        %169 = OpVectorShuffle %v3half %168 %168 2 0 1
+               OpStore %166 %169
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_storage.wgsl.expected.glsl
index e07c0f4..f55e780 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_storage.wgsl.expected.glsl
@@ -44,26 +44,35 @@
   S inner[4];
 } s;
 
+void assign_and_preserve_padding_2_s_X_m(uint dest[1], mat4x3 value) {
+  s.inner[dest[0]].m[0] = value[0u];
+  s.inner[dest[0]].m[1] = value[1u];
+  s.inner[dest[0]].m[2] = value[2u];
+  s.inner[dest[0]].m[3] = value[3u];
+}
+
 void assign_and_preserve_padding_1_s_X(uint dest[1], S value) {
   s.inner[dest[0]].before = value.before;
-  s.inner[dest[0]].m = value.m;
+  uint tint_symbol[1] = uint[1](dest[0u]);
+  assign_and_preserve_padding_2_s_X_m(tint_symbol, value.m);
   s.inner[dest[0]].after = value.after;
 }
 
 void assign_and_preserve_padding_s(S value[4]) {
   {
     for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-      uint tint_symbol[1] = uint[1](i);
-      assign_and_preserve_padding_1_s_X(tint_symbol, value[i]);
+      uint tint_symbol_1[1] = uint[1](i);
+      assign_and_preserve_padding_1_s_X(tint_symbol_1, value[i]);
     }
   }
 }
 
 void f() {
   assign_and_preserve_padding_s(u.inner);
-  uint tint_symbol_1[1] = uint[1](1u);
-  assign_and_preserve_padding_1_s_X(tint_symbol_1, u.inner[2]);
-  s.inner[3].m = u.inner[2].m;
+  uint tint_symbol_2[1] = uint[1](1u);
+  assign_and_preserve_padding_1_s_X(tint_symbol_2, u.inner[2]);
+  uint tint_symbol_3[1] = uint[1](3u);
+  assign_and_preserve_padding_2_s_X_m(tint_symbol_3, u.inner[2].m);
   s.inner[1].m[0] = u.inner[0].m[1].zxy;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_storage.wgsl.expected.msl
index ef3c702..6014fc4 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_storage.wgsl.expected.msl
@@ -23,9 +23,16 @@
   /* 0x0084 */ tint_array<int8_t, 60> tint_pad_2;
 };
 
+void assign_and_preserve_padding_2(device float4x3* const dest, float4x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+  (*(dest))[3u] = value[3u];
+}
+
 void assign_and_preserve_padding_1(device S* const dest, S value) {
   (*(dest)).before = value.before;
-  (*(dest)).m = value.m;
+  assign_and_preserve_padding_2(&((*(dest)).m), value.m);
   (*(dest)).after = value.after;
 }
 
@@ -38,7 +45,7 @@
 kernel void f(device tint_array<S, 4>* tint_symbol [[buffer(1)]], const constant tint_array<S, 4>* tint_symbol_1 [[buffer(0)]]) {
   assign_and_preserve_padding(tint_symbol, *(tint_symbol_1));
   assign_and_preserve_padding_1(&((*(tint_symbol))[1]), (*(tint_symbol_1))[2]);
-  (*(tint_symbol))[3].m = (*(tint_symbol_1))[2].m;
+  assign_and_preserve_padding_2(&((*(tint_symbol))[3].m), (*(tint_symbol_1))[2].m);
   (*(tint_symbol))[1].m[0] = float3((*(tint_symbol_1))[0].m[1]).zxy;
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_storage.wgsl.expected.spvasm
index 4b7013f..ac4af12 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 90
+; Bound: 109
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -15,11 +15,14 @@
                OpMemberName %S 2 "after"
                OpName %u "u"
                OpName %s "s"
-               OpName %assign_and_preserve_padding_1_s_X "assign_and_preserve_padding_1_s_X"
+               OpName %assign_and_preserve_padding_2_s_X_m "assign_and_preserve_padding_2_s_X_m"
                OpName %dest "dest"
                OpName %value "value"
-               OpName %assign_and_preserve_padding_s "assign_and_preserve_padding_s"
+               OpName %assign_and_preserve_padding_1_s_X "assign_and_preserve_padding_1_s_X"
+               OpName %dest_0 "dest"
                OpName %value_0 "value"
+               OpName %assign_and_preserve_padding_s "assign_and_preserve_padding_s"
+               OpName %value_1 "value"
                OpName %i "i"
                OpName %var_for_index "var_for_index"
                OpName %f "f"
@@ -53,98 +56,121 @@
        %void = OpTypeVoid
      %uint_1 = OpConstant %uint 1
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
-         %14 = OpTypeFunction %void %_arr_uint_uint_1 %S
+         %14 = OpTypeFunction %void %_arr_uint_uint_1 %mat4v3float
      %uint_0 = OpConstant %uint 0
          %23 = OpConstantNull %int
-%_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-%_ptr_StorageBuffer_mat4v3float = OpTypePointer StorageBuffer %mat4v3float
+%_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
+         %27 = OpConstantNull %uint
+      %int_1 = OpConstant %int 1
+      %int_2 = OpConstant %int 2
      %uint_2 = OpConstant %uint 2
-         %36 = OpTypeFunction %void %_arr_S_uint_4
-         %40 = OpConstantNull %uint
+      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
+         %43 = OpTypeFunction %void %_arr_uint_uint_1 %S
+%_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
+         %59 = OpTypeFunction %void %_arr_S_uint_4
 %_ptr_Function_uint = OpTypePointer Function %uint
        %bool = OpTypeBool
 %_ptr_Function__arr_S_uint_4 = OpTypePointer Function %_arr_S_uint_4
-         %55 = OpConstantNull %_arr_S_uint_4
+         %77 = OpConstantNull %_arr_S_uint_4
 %_ptr_Function_S = OpTypePointer Function %S
-         %65 = OpTypeFunction %void
+         %87 = OpTypeFunction %void
 %_ptr_Uniform__arr_S_uint_4 = OpTypePointer Uniform %_arr_S_uint_4
-         %73 = OpConstantComposite %_arr_uint_uint_1 %uint_1
-      %int_2 = OpConstant %int 2
+         %95 = OpConstantComposite %_arr_uint_uint_1 %uint_1
 %_ptr_Uniform_S = OpTypePointer Uniform %S
-      %int_3 = OpConstant %int 3
+        %100 = OpConstantComposite %_arr_uint_uint_1 %uint_3
 %_ptr_Uniform_mat4v3float = OpTypePointer Uniform %mat4v3float
-      %int_1 = OpConstant %int 1
-%_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
-%assign_and_preserve_padding_1_s_X = OpFunction %void None %14
+%assign_and_preserve_padding_2_s_X_m = OpFunction %void None %14
        %dest = OpFunctionParameter %_arr_uint_uint_1
-      %value = OpFunctionParameter %S
+      %value = OpFunctionParameter %mat4v3float
          %21 = OpLabel
          %24 = OpCompositeExtract %uint %dest 0
-         %26 = OpAccessChain %_ptr_StorageBuffer_int %s %uint_0 %24 %uint_0
-         %27 = OpCompositeExtract %int %value 0
-               OpStore %26 %27
-         %28 = OpCompositeExtract %uint %dest 0
-         %30 = OpAccessChain %_ptr_StorageBuffer_mat4v3float %s %uint_0 %28 %uint_1
-         %31 = OpCompositeExtract %mat4v3float %value 1
-               OpStore %30 %31
-         %32 = OpCompositeExtract %uint %dest 0
-         %34 = OpAccessChain %_ptr_StorageBuffer_int %s %uint_0 %32 %uint_2
-         %35 = OpCompositeExtract %int %value 2
-               OpStore %34 %35
+         %26 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %24 %uint_1 %23
+         %28 = OpCompositeExtract %v3float %value 0
+               OpStore %26 %28
+         %29 = OpCompositeExtract %uint %dest 0
+         %31 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %29 %uint_1 %int_1
+         %32 = OpCompositeExtract %v3float %value 1
+               OpStore %31 %32
+         %33 = OpCompositeExtract %uint %dest 0
+         %35 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %33 %uint_1 %int_2
+         %37 = OpCompositeExtract %v3float %value 2
+               OpStore %35 %37
+         %38 = OpCompositeExtract %uint %dest 0
+         %40 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %38 %uint_1 %int_3
+         %42 = OpCompositeExtract %v3float %value 3
+               OpStore %40 %42
                OpReturn
                OpFunctionEnd
-%assign_and_preserve_padding_s = OpFunction %void None %36
-    %value_0 = OpFunctionParameter %_arr_S_uint_4
-         %39 = OpLabel
-          %i = OpVariable %_ptr_Function_uint Function %40
-%var_for_index = OpVariable %_ptr_Function__arr_S_uint_4 Function %55
-               OpStore %i %40
-               OpBranch %43
-         %43 = OpLabel
-               OpLoopMerge %44 %45 None
-               OpBranch %46
-         %46 = OpLabel
-         %48 = OpLoad %uint %i
-         %49 = OpULessThan %bool %48 %uint_4
-         %47 = OpLogicalNot %bool %49
-               OpSelectionMerge %51 None
-               OpBranchConditional %47 %52 %51
-         %52 = OpLabel
-               OpBranch %44
-         %51 = OpLabel
-               OpStore %var_for_index %value_0
-         %57 = OpLoad %uint %i
-         %58 = OpCompositeConstruct %_arr_uint_uint_1 %57
-         %59 = OpLoad %uint %i
-         %61 = OpAccessChain %_ptr_Function_S %var_for_index %59
-         %62 = OpLoad %S %61
-         %56 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %58 %62
-               OpBranch %45
-         %45 = OpLabel
-         %63 = OpLoad %uint %i
-         %64 = OpIAdd %uint %63 %uint_1
-               OpStore %i %64
-               OpBranch %43
-         %44 = OpLabel
+%assign_and_preserve_padding_1_s_X = OpFunction %void None %43
+     %dest_0 = OpFunctionParameter %_arr_uint_uint_1
+    %value_0 = OpFunctionParameter %S
+         %47 = OpLabel
+         %48 = OpCompositeExtract %uint %dest_0 0
+         %50 = OpAccessChain %_ptr_StorageBuffer_int %s %uint_0 %48 %uint_0
+         %51 = OpCompositeExtract %int %value_0 0
+               OpStore %50 %51
+         %53 = OpCompositeExtract %uint %dest_0 0
+         %54 = OpCompositeConstruct %_arr_uint_uint_1 %53
+         %55 = OpCompositeExtract %mat4v3float %value_0 1
+         %52 = OpFunctionCall %void %assign_and_preserve_padding_2_s_X_m %54 %55
+         %56 = OpCompositeExtract %uint %dest_0 0
+         %57 = OpAccessChain %_ptr_StorageBuffer_int %s %uint_0 %56 %uint_2
+         %58 = OpCompositeExtract %int %value_0 2
+               OpStore %57 %58
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %65
+%assign_and_preserve_padding_s = OpFunction %void None %59
+    %value_1 = OpFunctionParameter %_arr_S_uint_4
+         %62 = OpLabel
+          %i = OpVariable %_ptr_Function_uint Function %27
+%var_for_index = OpVariable %_ptr_Function__arr_S_uint_4 Function %77
+               OpStore %i %27
+               OpBranch %65
+         %65 = OpLabel
+               OpLoopMerge %66 %67 None
+               OpBranch %68
+         %68 = OpLabel
+         %70 = OpLoad %uint %i
+         %71 = OpULessThan %bool %70 %uint_4
+         %69 = OpLogicalNot %bool %71
+               OpSelectionMerge %73 None
+               OpBranchConditional %69 %74 %73
+         %74 = OpLabel
+               OpBranch %66
+         %73 = OpLabel
+               OpStore %var_for_index %value_1
+         %79 = OpLoad %uint %i
+         %80 = OpCompositeConstruct %_arr_uint_uint_1 %79
+         %81 = OpLoad %uint %i
+         %83 = OpAccessChain %_ptr_Function_S %var_for_index %81
+         %84 = OpLoad %S %83
+         %78 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %80 %84
+               OpBranch %67
          %67 = OpLabel
-         %70 = OpAccessChain %_ptr_Uniform__arr_S_uint_4 %u %uint_0
-         %71 = OpLoad %_arr_S_uint_4 %70
-         %68 = OpFunctionCall %void %assign_and_preserve_padding_s %71
-         %76 = OpAccessChain %_ptr_Uniform_S %u %uint_0 %int_2
-         %77 = OpLoad %S %76
-         %72 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %73 %77
-         %79 = OpAccessChain %_ptr_StorageBuffer_mat4v3float %s %uint_0 %int_3 %uint_1
-         %81 = OpAccessChain %_ptr_Uniform_mat4v3float %u %uint_0 %int_2 %uint_1
-         %82 = OpLoad %mat4v3float %81
-               OpStore %79 %82
-         %85 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %int_1 %uint_1 %23
-         %87 = OpAccessChain %_ptr_Uniform_v3float %u %uint_0 %23 %uint_1 %int_1
-         %88 = OpLoad %v3float %87
-         %89 = OpVectorShuffle %v3float %88 %88 2 0 1
-               OpStore %85 %89
+         %85 = OpLoad %uint %i
+         %86 = OpIAdd %uint %85 %uint_1
+               OpStore %i %86
+               OpBranch %65
+         %66 = OpLabel
+               OpReturn
+               OpFunctionEnd
+          %f = OpFunction %void None %87
+         %89 = OpLabel
+         %92 = OpAccessChain %_ptr_Uniform__arr_S_uint_4 %u %uint_0
+         %93 = OpLoad %_arr_S_uint_4 %92
+         %90 = OpFunctionCall %void %assign_and_preserve_padding_s %93
+         %97 = OpAccessChain %_ptr_Uniform_S %u %uint_0 %int_2
+         %98 = OpLoad %S %97
+         %94 = OpFunctionCall %void %assign_and_preserve_padding_1_s_X %95 %98
+        %102 = OpAccessChain %_ptr_Uniform_mat4v3float %u %uint_0 %int_2 %uint_1
+        %103 = OpLoad %mat4v3float %102
+         %99 = OpFunctionCall %void %assign_and_preserve_padding_2_s_X_m %100 %103
+        %104 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %int_1 %uint_1 %23
+        %106 = OpAccessChain %_ptr_Uniform_v3float %u %uint_0 %23 %uint_1 %int_1
+        %107 = OpLoad %v3float %106
+        %108 = OpVectorShuffle %v3float %107 %107 2 0 1
+               OpStore %104 %108
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_storage.wgsl.expected.glsl
index ba0c55a..c8fb8a6 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_storage.wgsl.expected.glsl
@@ -10,12 +10,17 @@
   f16mat2x3 inner;
 } s;
 
+void assign_and_preserve_padding_s(f16mat2x3 value) {
+  s.inner[0] = value[0u];
+  s.inner[1] = value[1u];
+}
+
 f16mat2x3 load_u_inner() {
   return f16mat2x3(u.inner_0, u.inner_1);
 }
 
 void f() {
-  s.inner = load_u_inner();
+  assign_and_preserve_padding_s(load_u_inner());
   s.inner[1] = u.inner_0;
   s.inner[1] = u.inner_0.zxy;
   s.inner[0][1] = u.inner_1[0u];
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_storage.wgsl.expected.msl
index 495bebf..4661a71 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_storage.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+void assign_and_preserve_padding(device half2x3* const dest, half2x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+}
+
 kernel void f(device half2x3* tint_symbol [[buffer(1)]], const constant half2x3* tint_symbol_1 [[buffer(0)]]) {
-  *(tint_symbol) = *(tint_symbol_1);
+  assign_and_preserve_padding(tint_symbol, *(tint_symbol_1));
   (*(tint_symbol))[1] = (*(tint_symbol_1))[0];
   (*(tint_symbol))[1] = half3((*(tint_symbol_1))[0]).zxy;
   (*(tint_symbol))[0][1] = (*(tint_symbol_1))[1][0];
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_storage.wgsl.expected.spvasm
index 67096f3..8cb1c45 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 49
+; Bound: 56
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -18,6 +18,8 @@
                OpName %u_block "u_block"
                OpMemberName %u_block 0 "inner"
                OpName %s "s"
+               OpName %assign_and_preserve_padding_s "assign_and_preserve_padding_s"
+               OpName %value "value"
                OpName %load_u_inner "load_u_inner"
                OpName %f "f"
                OpDecorate %u_block_std140 Block
@@ -41,47 +43,57 @@
     %u_block = OpTypeStruct %mat2v3half
 %_ptr_StorageBuffer_u_block = OpTypePointer StorageBuffer %u_block
           %s = OpVariable %_ptr_StorageBuffer_u_block StorageBuffer
-         %10 = OpTypeFunction %mat2v3half
+       %void = OpTypeVoid
+         %10 = OpTypeFunction %void %mat2v3half
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
-%_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
-     %uint_1 = OpConstant %uint 1
-       %void = OpTypeVoid
-         %25 = OpTypeFunction %void
-%_ptr_StorageBuffer_mat2v3half = OpTypePointer StorageBuffer %mat2v3half
         %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
+         %18 = OpConstantNull %int
 %_ptr_StorageBuffer_v3half = OpTypePointer StorageBuffer %v3half
-         %42 = OpConstantNull %int
+         %21 = OpConstantNull %uint
+      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
+         %27 = OpTypeFunction %mat2v3half
+%_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
-         %45 = OpConstantNull %uint
 %_ptr_Uniform_half = OpTypePointer Uniform %half
-%load_u_inner = OpFunction %mat2v3half None %10
-         %12 = OpLabel
-         %18 = OpAccessChain %_ptr_Uniform_v3half %u %uint_0
-         %19 = OpLoad %v3half %18
-         %22 = OpAccessChain %_ptr_Uniform_v3half %u %uint_1
-         %23 = OpLoad %v3half %22
-         %24 = OpCompositeConstruct %mat2v3half %19 %23
-               OpReturnValue %24
+%assign_and_preserve_padding_s = OpFunction %void None %10
+      %value = OpFunctionParameter %mat2v3half
+         %14 = OpLabel
+         %20 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %18
+         %22 = OpCompositeExtract %v3half %value 0
+               OpStore %20 %22
+         %24 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %int_1
+         %26 = OpCompositeExtract %v3half %value 1
+               OpStore %24 %26
+               OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %25
-         %28 = OpLabel
-         %30 = OpAccessChain %_ptr_StorageBuffer_mat2v3half %s %uint_0
-         %31 = OpFunctionCall %mat2v3half %load_u_inner
-               OpStore %30 %31
-         %35 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %int_1
-         %36 = OpAccessChain %_ptr_Uniform_v3half %u %uint_0
+%load_u_inner = OpFunction %mat2v3half None %27
+         %29 = OpLabel
+         %33 = OpAccessChain %_ptr_Uniform_v3half %u %uint_0
+         %34 = OpLoad %v3half %33
+         %36 = OpAccessChain %_ptr_Uniform_v3half %u %uint_1
          %37 = OpLoad %v3half %36
-               OpStore %35 %37
-         %38 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %int_1
-         %39 = OpAccessChain %_ptr_Uniform_v3half %u %uint_0
-         %40 = OpLoad %v3half %39
-         %41 = OpVectorShuffle %v3half %40 %40 2 0 1
-               OpStore %38 %41
-         %44 = OpAccessChain %_ptr_StorageBuffer_half %s %uint_0 %42 %int_1
-         %47 = OpAccessChain %_ptr_Uniform_half %u %uint_1 %45
-         %48 = OpLoad %half %47
-               OpStore %44 %48
+         %38 = OpCompositeConstruct %mat2v3half %34 %37
+               OpReturnValue %38
+               OpFunctionEnd
+          %f = OpFunction %void None %39
+         %41 = OpLabel
+         %43 = OpFunctionCall %mat2v3half %load_u_inner
+         %42 = OpFunctionCall %void %assign_and_preserve_padding_s %43
+         %44 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %int_1
+         %45 = OpAccessChain %_ptr_Uniform_v3half %u %uint_0
+         %46 = OpLoad %v3half %45
+               OpStore %44 %46
+         %47 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %int_1
+         %48 = OpAccessChain %_ptr_Uniform_v3half %u %uint_0
+         %49 = OpLoad %v3half %48
+         %50 = OpVectorShuffle %v3half %49 %49 2 0 1
+               OpStore %47 %50
+         %52 = OpAccessChain %_ptr_StorageBuffer_half %s %uint_0 %18 %int_1
+         %54 = OpAccessChain %_ptr_Uniform_half %u %uint_1 %21
+         %55 = OpLoad %half %54
+               OpStore %52 %55
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_storage.wgsl.expected.glsl
index bd4b73c..cacdf32 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_storage.wgsl.expected.glsl
@@ -8,8 +8,13 @@
   mat2x3 inner;
 } s;
 
+void assign_and_preserve_padding_s(mat2x3 value) {
+  s.inner[0] = value[0u];
+  s.inner[1] = value[1u];
+}
+
 void f() {
-  s.inner = u.inner;
+  assign_and_preserve_padding_s(u.inner);
   s.inner[1] = u.inner[0];
   s.inner[1] = u.inner[0].zxy;
   s.inner[0][1] = u.inner[1][0];
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_storage.wgsl.expected.msl
index 59569b4..670bceb 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_storage.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+void assign_and_preserve_padding(device float2x3* const dest, float2x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+}
+
 kernel void f(device float2x3* tint_symbol [[buffer(1)]], const constant float2x3* tint_symbol_1 [[buffer(0)]]) {
-  *(tint_symbol) = *(tint_symbol_1);
+  assign_and_preserve_padding(tint_symbol, *(tint_symbol_1));
   (*(tint_symbol))[1] = (*(tint_symbol_1))[0];
   (*(tint_symbol))[1] = float3((*(tint_symbol_1))[0]).zxy;
   (*(tint_symbol))[0][1] = (*(tint_symbol_1))[1][0];
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_storage.wgsl.expected.spvasm
index faf129f..99f22aa 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 37
+; Bound: 46
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -11,6 +11,8 @@
                OpMemberName %u_block 0 "inner"
                OpName %u "u"
                OpName %s "s"
+               OpName %assign_and_preserve_padding_s "assign_and_preserve_padding_s"
+               OpName %value "value"
                OpName %f "f"
                OpDecorate %u_block Block
                OpMemberDecorate %u_block 0 Offset 0
@@ -30,36 +32,48 @@
 %_ptr_StorageBuffer_u_block = OpTypePointer StorageBuffer %u_block
           %s = OpVariable %_ptr_StorageBuffer_u_block StorageBuffer
        %void = OpTypeVoid
-          %9 = OpTypeFunction %void
+          %9 = OpTypeFunction %void %mat2v3float
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
-%_ptr_StorageBuffer_mat2v3float = OpTypePointer StorageBuffer %mat2v3float
-%_ptr_Uniform_mat2v3float = OpTypePointer Uniform %mat2v3float
         %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
+         %17 = OpConstantNull %int
 %_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
-         %24 = OpConstantNull %int
+         %20 = OpConstantNull %uint
+      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
+         %26 = OpTypeFunction %void
+%_ptr_Uniform_mat2v3float = OpTypePointer Uniform %mat2v3float
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
 %_ptr_Uniform_float = OpTypePointer Uniform %float
-          %f = OpFunction %void None %9
-         %12 = OpLabel
-         %16 = OpAccessChain %_ptr_StorageBuffer_mat2v3float %s %uint_0
-         %18 = OpAccessChain %_ptr_Uniform_mat2v3float %u %uint_0
-         %19 = OpLoad %mat2v3float %18
-               OpStore %16 %19
+%assign_and_preserve_padding_s = OpFunction %void None %9
+      %value = OpFunctionParameter %mat2v3float
+         %13 = OpLabel
+         %19 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %17
+         %21 = OpCompositeExtract %v3float %value 0
+               OpStore %19 %21
          %23 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %int_1
-         %26 = OpAccessChain %_ptr_Uniform_v3float %u %uint_0 %24
-         %27 = OpLoad %v3float %26
-               OpStore %23 %27
-         %28 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %int_1
-         %29 = OpAccessChain %_ptr_Uniform_v3float %u %uint_0 %24
-         %30 = OpLoad %v3float %29
-         %31 = OpVectorShuffle %v3float %30 %30 2 0 1
-               OpStore %28 %31
-         %33 = OpAccessChain %_ptr_StorageBuffer_float %s %uint_0 %24 %int_1
-         %35 = OpAccessChain %_ptr_Uniform_float %u %uint_0 %int_1 %24
-         %36 = OpLoad %float %35
+         %25 = OpCompositeExtract %v3float %value 1
+               OpStore %23 %25
+               OpReturn
+               OpFunctionEnd
+          %f = OpFunction %void None %26
+         %28 = OpLabel
+         %31 = OpAccessChain %_ptr_Uniform_mat2v3float %u %uint_0
+         %32 = OpLoad %mat2v3float %31
+         %29 = OpFunctionCall %void %assign_and_preserve_padding_s %32
+         %33 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %int_1
+         %35 = OpAccessChain %_ptr_Uniform_v3float %u %uint_0 %17
+         %36 = OpLoad %v3float %35
                OpStore %33 %36
+         %37 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %int_1
+         %38 = OpAccessChain %_ptr_Uniform_v3float %u %uint_0 %17
+         %39 = OpLoad %v3float %38
+         %40 = OpVectorShuffle %v3float %39 %39 2 0 1
+               OpStore %37 %40
+         %42 = OpAccessChain %_ptr_StorageBuffer_float %s %uint_0 %17 %int_1
+         %44 = OpAccessChain %_ptr_Uniform_float %u %uint_0 %int_1 %17
+         %45 = OpLoad %float %44
+               OpStore %42 %45
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_storage.wgsl.expected.glsl
index 740aecc..cf594f3 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_storage.wgsl.expected.glsl
@@ -11,12 +11,18 @@
   f16mat3 inner;
 } s;
 
+void assign_and_preserve_padding_s(f16mat3 value) {
+  s.inner[0] = value[0u];
+  s.inner[1] = value[1u];
+  s.inner[2] = value[2u];
+}
+
 f16mat3 load_u_inner() {
   return f16mat3(u.inner_0, u.inner_1, u.inner_2);
 }
 
 void f() {
-  s.inner = load_u_inner();
+  assign_and_preserve_padding_s(load_u_inner());
   s.inner[1] = u.inner_0;
   s.inner[1] = u.inner_0.zxy;
   s.inner[0][1] = u.inner_1[0u];
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_storage.wgsl.expected.msl
index 88e665b..e621117 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_storage.wgsl.expected.msl
@@ -1,8 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+void assign_and_preserve_padding(device half3x3* const dest, half3x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+}
+
 kernel void f(device half3x3* tint_symbol [[buffer(1)]], const constant half3x3* tint_symbol_1 [[buffer(0)]]) {
-  *(tint_symbol) = *(tint_symbol_1);
+  assign_and_preserve_padding(tint_symbol, *(tint_symbol_1));
   (*(tint_symbol))[1] = (*(tint_symbol_1))[0];
   (*(tint_symbol))[1] = half3((*(tint_symbol_1))[0]).zxy;
   (*(tint_symbol))[0][1] = (*(tint_symbol_1))[1][0];
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_storage.wgsl.expected.spvasm
index 405f643..5c90ce6 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 53
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -19,6 +19,8 @@
                OpName %u_block "u_block"
                OpMemberName %u_block 0 "inner"
                OpName %s "s"
+               OpName %assign_and_preserve_padding_s "assign_and_preserve_padding_s"
+               OpName %value "value"
                OpName %load_u_inner "load_u_inner"
                OpName %f "f"
                OpDecorate %u_block_std140 Block
@@ -43,50 +45,64 @@
     %u_block = OpTypeStruct %mat3v3half
 %_ptr_StorageBuffer_u_block = OpTypePointer StorageBuffer %u_block
           %s = OpVariable %_ptr_StorageBuffer_u_block StorageBuffer
-         %10 = OpTypeFunction %mat3v3half
+       %void = OpTypeVoid
+         %10 = OpTypeFunction %void %mat3v3half
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
-%_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
-     %uint_1 = OpConstant %uint 1
-     %uint_2 = OpConstant %uint 2
-       %void = OpTypeVoid
-         %29 = OpTypeFunction %void
-%_ptr_StorageBuffer_mat3v3half = OpTypePointer StorageBuffer %mat3v3half
         %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
+         %18 = OpConstantNull %int
 %_ptr_StorageBuffer_v3half = OpTypePointer StorageBuffer %v3half
-         %46 = OpConstantNull %int
+         %21 = OpConstantNull %uint
+      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
+      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
+         %31 = OpTypeFunction %mat3v3half
+%_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
-         %49 = OpConstantNull %uint
 %_ptr_Uniform_half = OpTypePointer Uniform %half
-%load_u_inner = OpFunction %mat3v3half None %10
-         %12 = OpLabel
-         %18 = OpAccessChain %_ptr_Uniform_v3half %u %uint_0
-         %19 = OpLoad %v3half %18
-         %22 = OpAccessChain %_ptr_Uniform_v3half %u %uint_1
-         %23 = OpLoad %v3half %22
-         %26 = OpAccessChain %_ptr_Uniform_v3half %u %uint_2
-         %27 = OpLoad %v3half %26
-         %28 = OpCompositeConstruct %mat3v3half %19 %23 %27
-               OpReturnValue %28
+%assign_and_preserve_padding_s = OpFunction %void None %10
+      %value = OpFunctionParameter %mat3v3half
+         %14 = OpLabel
+         %20 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %18
+         %22 = OpCompositeExtract %v3half %value 0
+               OpStore %20 %22
+         %24 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %int_1
+         %26 = OpCompositeExtract %v3half %value 1
+               OpStore %24 %26
+         %28 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %int_2
+         %30 = OpCompositeExtract %v3half %value 2
+               OpStore %28 %30
+               OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %29
-         %32 = OpLabel
-         %34 = OpAccessChain %_ptr_StorageBuffer_mat3v3half %s %uint_0
-         %35 = OpFunctionCall %mat3v3half %load_u_inner
-               OpStore %34 %35
-         %39 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %int_1
-         %40 = OpAccessChain %_ptr_Uniform_v3half %u %uint_0
+%load_u_inner = OpFunction %mat3v3half None %31
+         %33 = OpLabel
+         %37 = OpAccessChain %_ptr_Uniform_v3half %u %uint_0
+         %38 = OpLoad %v3half %37
+         %40 = OpAccessChain %_ptr_Uniform_v3half %u %uint_1
          %41 = OpLoad %v3half %40
-               OpStore %39 %41
-         %42 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %int_1
-         %43 = OpAccessChain %_ptr_Uniform_v3half %u %uint_0
+         %43 = OpAccessChain %_ptr_Uniform_v3half %u %uint_2
          %44 = OpLoad %v3half %43
-         %45 = OpVectorShuffle %v3half %44 %44 2 0 1
-               OpStore %42 %45
-         %48 = OpAccessChain %_ptr_StorageBuffer_half %s %uint_0 %46 %int_1
-         %51 = OpAccessChain %_ptr_Uniform_half %u %uint_1 %49
-         %52 = OpLoad %half %51
-               OpStore %48 %52
+         %45 = OpCompositeConstruct %mat3v3half %38 %41 %44
+               OpReturnValue %45
+               OpFunctionEnd
+          %f = OpFunction %void None %46
+         %48 = OpLabel
+         %50 = OpFunctionCall %mat3v3half %load_u_inner
+         %49 = OpFunctionCall %void %assign_and_preserve_padding_s %50
+         %51 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %int_1
+         %52 = OpAccessChain %_ptr_Uniform_v3half %u %uint_0
+         %53 = OpLoad %v3half %52
+               OpStore %51 %53
+         %54 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %int_1
+         %55 = OpAccessChain %_ptr_Uniform_v3half %u %uint_0
+         %56 = OpLoad %v3half %55
+         %57 = OpVectorShuffle %v3half %56 %56 2 0 1
+               OpStore %54 %57
+         %59 = OpAccessChain %_ptr_StorageBuffer_half %s %uint_0 %18 %int_1
+         %61 = OpAccessChain %_ptr_Uniform_half %u %uint_1 %21
+         %62 = OpLoad %half %61
+               OpStore %59 %62
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_storage.wgsl.expected.glsl
index 2e910e8..2761b20 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_storage.wgsl.expected.glsl
@@ -8,8 +8,14 @@
   mat3 inner;
 } s;
 
+void assign_and_preserve_padding_s(mat3 value) {
+  s.inner[0] = value[0u];
+  s.inner[1] = value[1u];
+  s.inner[2] = value[2u];
+}
+
 void f() {
-  s.inner = u.inner;
+  assign_and_preserve_padding_s(u.inner);
   s.inner[1] = u.inner[0];
   s.inner[1] = u.inner[0].zxy;
   s.inner[0][1] = u.inner[1][0];
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_storage.wgsl.expected.msl
index 207c6b0..f7b9608 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_storage.wgsl.expected.msl
@@ -1,8 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+void assign_and_preserve_padding(device float3x3* const dest, float3x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+}
+
 kernel void f(device float3x3* tint_symbol [[buffer(1)]], const constant float3x3* tint_symbol_1 [[buffer(0)]]) {
-  *(tint_symbol) = *(tint_symbol_1);
+  assign_and_preserve_padding(tint_symbol, *(tint_symbol_1));
   (*(tint_symbol))[1] = (*(tint_symbol_1))[0];
   (*(tint_symbol))[1] = float3((*(tint_symbol_1))[0]).zxy;
   (*(tint_symbol))[0][1] = (*(tint_symbol_1))[1][0];
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_storage.wgsl.expected.spvasm
index fd0a6f8..7d9db58 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 37
+; Bound: 50
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -11,6 +11,8 @@
                OpMemberName %u_block 0 "inner"
                OpName %u "u"
                OpName %s "s"
+               OpName %assign_and_preserve_padding_s "assign_and_preserve_padding_s"
+               OpName %value "value"
                OpName %f "f"
                OpDecorate %u_block Block
                OpMemberDecorate %u_block 0 Offset 0
@@ -30,36 +32,53 @@
 %_ptr_StorageBuffer_u_block = OpTypePointer StorageBuffer %u_block
           %s = OpVariable %_ptr_StorageBuffer_u_block StorageBuffer
        %void = OpTypeVoid
-          %9 = OpTypeFunction %void
+          %9 = OpTypeFunction %void %mat3v3float
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
-%_ptr_StorageBuffer_mat3v3float = OpTypePointer StorageBuffer %mat3v3float
-%_ptr_Uniform_mat3v3float = OpTypePointer Uniform %mat3v3float
         %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
+         %17 = OpConstantNull %int
 %_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
-         %24 = OpConstantNull %int
+         %20 = OpConstantNull %uint
+      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
+      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
+         %30 = OpTypeFunction %void
+%_ptr_Uniform_mat3v3float = OpTypePointer Uniform %mat3v3float
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
 %_ptr_Uniform_float = OpTypePointer Uniform %float
-          %f = OpFunction %void None %9
-         %12 = OpLabel
-         %16 = OpAccessChain %_ptr_StorageBuffer_mat3v3float %s %uint_0
-         %18 = OpAccessChain %_ptr_Uniform_mat3v3float %u %uint_0
-         %19 = OpLoad %mat3v3float %18
-               OpStore %16 %19
+%assign_and_preserve_padding_s = OpFunction %void None %9
+      %value = OpFunctionParameter %mat3v3float
+         %13 = OpLabel
+         %19 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %17
+         %21 = OpCompositeExtract %v3float %value 0
+               OpStore %19 %21
          %23 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %int_1
-         %26 = OpAccessChain %_ptr_Uniform_v3float %u %uint_0 %24
-         %27 = OpLoad %v3float %26
-               OpStore %23 %27
-         %28 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %int_1
-         %29 = OpAccessChain %_ptr_Uniform_v3float %u %uint_0 %24
-         %30 = OpLoad %v3float %29
-         %31 = OpVectorShuffle %v3float %30 %30 2 0 1
-               OpStore %28 %31
-         %33 = OpAccessChain %_ptr_StorageBuffer_float %s %uint_0 %24 %int_1
-         %35 = OpAccessChain %_ptr_Uniform_float %u %uint_0 %int_1 %24
-         %36 = OpLoad %float %35
-               OpStore %33 %36
+         %25 = OpCompositeExtract %v3float %value 1
+               OpStore %23 %25
+         %27 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %int_2
+         %29 = OpCompositeExtract %v3float %value 2
+               OpStore %27 %29
+               OpReturn
+               OpFunctionEnd
+          %f = OpFunction %void None %30
+         %32 = OpLabel
+         %35 = OpAccessChain %_ptr_Uniform_mat3v3float %u %uint_0
+         %36 = OpLoad %mat3v3float %35
+         %33 = OpFunctionCall %void %assign_and_preserve_padding_s %36
+         %37 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %int_1
+         %39 = OpAccessChain %_ptr_Uniform_v3float %u %uint_0 %17
+         %40 = OpLoad %v3float %39
+               OpStore %37 %40
+         %41 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %int_1
+         %42 = OpAccessChain %_ptr_Uniform_v3float %u %uint_0 %17
+         %43 = OpLoad %v3float %42
+         %44 = OpVectorShuffle %v3float %43 %43 2 0 1
+               OpStore %41 %44
+         %46 = OpAccessChain %_ptr_StorageBuffer_float %s %uint_0 %17 %int_1
+         %48 = OpAccessChain %_ptr_Uniform_float %u %uint_0 %int_1 %17
+         %49 = OpLoad %float %48
+               OpStore %46 %49
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_storage.wgsl.expected.glsl
index dd054eb..c866784 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_storage.wgsl.expected.glsl
@@ -12,12 +12,19 @@
   f16mat4x3 inner;
 } s;
 
+void assign_and_preserve_padding_s(f16mat4x3 value) {
+  s.inner[0] = value[0u];
+  s.inner[1] = value[1u];
+  s.inner[2] = value[2u];
+  s.inner[3] = value[3u];
+}
+
 f16mat4x3 load_u_inner() {
   return f16mat4x3(u.inner_0, u.inner_1, u.inner_2, u.inner_3);
 }
 
 void f() {
-  s.inner = load_u_inner();
+  assign_and_preserve_padding_s(load_u_inner());
   s.inner[1] = u.inner_0;
   s.inner[1] = u.inner_0.zxy;
   s.inner[0][1] = u.inner_1[0u];
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_storage.wgsl.expected.msl
index cab8651..4b84184 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_storage.wgsl.expected.msl
@@ -1,8 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+void assign_and_preserve_padding(device half4x3* const dest, half4x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+  (*(dest))[3u] = value[3u];
+}
+
 kernel void f(device half4x3* tint_symbol [[buffer(1)]], const constant half4x3* tint_symbol_1 [[buffer(0)]]) {
-  *(tint_symbol) = *(tint_symbol_1);
+  assign_and_preserve_padding(tint_symbol, *(tint_symbol_1));
   (*(tint_symbol))[1] = (*(tint_symbol_1))[0];
   (*(tint_symbol))[1] = half3((*(tint_symbol_1))[0]).zxy;
   (*(tint_symbol))[0][1] = (*(tint_symbol_1))[1][0];
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_storage.wgsl.expected.spvasm
index d22bb08..104cfd5 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 57
+; Bound: 70
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -20,6 +20,8 @@
                OpName %u_block "u_block"
                OpMemberName %u_block 0 "inner"
                OpName %s "s"
+               OpName %assign_and_preserve_padding_s "assign_and_preserve_padding_s"
+               OpName %value "value"
                OpName %load_u_inner "load_u_inner"
                OpName %f "f"
                OpDecorate %u_block_std140 Block
@@ -45,53 +47,71 @@
     %u_block = OpTypeStruct %mat4v3half
 %_ptr_StorageBuffer_u_block = OpTypePointer StorageBuffer %u_block
           %s = OpVariable %_ptr_StorageBuffer_u_block StorageBuffer
-         %10 = OpTypeFunction %mat4v3half
+       %void = OpTypeVoid
+         %10 = OpTypeFunction %void %mat4v3half
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
-%_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
-     %uint_1 = OpConstant %uint 1
-     %uint_2 = OpConstant %uint 2
-     %uint_3 = OpConstant %uint 3
-       %void = OpTypeVoid
-         %33 = OpTypeFunction %void
-%_ptr_StorageBuffer_mat4v3half = OpTypePointer StorageBuffer %mat4v3half
         %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
+         %18 = OpConstantNull %int
 %_ptr_StorageBuffer_v3half = OpTypePointer StorageBuffer %v3half
-         %50 = OpConstantNull %int
+         %21 = OpConstantNull %uint
+      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
+      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
+      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
+         %35 = OpTypeFunction %mat4v3half
+%_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
+         %53 = OpTypeFunction %void
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
-         %53 = OpConstantNull %uint
 %_ptr_Uniform_half = OpTypePointer Uniform %half
-%load_u_inner = OpFunction %mat4v3half None %10
-         %12 = OpLabel
-         %18 = OpAccessChain %_ptr_Uniform_v3half %u %uint_0
-         %19 = OpLoad %v3half %18
-         %22 = OpAccessChain %_ptr_Uniform_v3half %u %uint_1
-         %23 = OpLoad %v3half %22
-         %26 = OpAccessChain %_ptr_Uniform_v3half %u %uint_2
-         %27 = OpLoad %v3half %26
-         %30 = OpAccessChain %_ptr_Uniform_v3half %u %uint_3
-         %31 = OpLoad %v3half %30
-         %32 = OpCompositeConstruct %mat4v3half %19 %23 %27 %31
-               OpReturnValue %32
+%assign_and_preserve_padding_s = OpFunction %void None %10
+      %value = OpFunctionParameter %mat4v3half
+         %14 = OpLabel
+         %20 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %18
+         %22 = OpCompositeExtract %v3half %value 0
+               OpStore %20 %22
+         %24 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %int_1
+         %26 = OpCompositeExtract %v3half %value 1
+               OpStore %24 %26
+         %28 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %int_2
+         %30 = OpCompositeExtract %v3half %value 2
+               OpStore %28 %30
+         %32 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %int_3
+         %34 = OpCompositeExtract %v3half %value 3
+               OpStore %32 %34
+               OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %33
-         %36 = OpLabel
-         %38 = OpAccessChain %_ptr_StorageBuffer_mat4v3half %s %uint_0
-         %39 = OpFunctionCall %mat4v3half %load_u_inner
-               OpStore %38 %39
-         %43 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %int_1
-         %44 = OpAccessChain %_ptr_Uniform_v3half %u %uint_0
+%load_u_inner = OpFunction %mat4v3half None %35
+         %37 = OpLabel
+         %41 = OpAccessChain %_ptr_Uniform_v3half %u %uint_0
+         %42 = OpLoad %v3half %41
+         %44 = OpAccessChain %_ptr_Uniform_v3half %u %uint_1
          %45 = OpLoad %v3half %44
-               OpStore %43 %45
-         %46 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %int_1
-         %47 = OpAccessChain %_ptr_Uniform_v3half %u %uint_0
+         %47 = OpAccessChain %_ptr_Uniform_v3half %u %uint_2
          %48 = OpLoad %v3half %47
-         %49 = OpVectorShuffle %v3half %48 %48 2 0 1
-               OpStore %46 %49
-         %52 = OpAccessChain %_ptr_StorageBuffer_half %s %uint_0 %50 %int_1
-         %55 = OpAccessChain %_ptr_Uniform_half %u %uint_1 %53
-         %56 = OpLoad %half %55
-               OpStore %52 %56
+         %50 = OpAccessChain %_ptr_Uniform_v3half %u %uint_3
+         %51 = OpLoad %v3half %50
+         %52 = OpCompositeConstruct %mat4v3half %42 %45 %48 %51
+               OpReturnValue %52
+               OpFunctionEnd
+          %f = OpFunction %void None %53
+         %55 = OpLabel
+         %57 = OpFunctionCall %mat4v3half %load_u_inner
+         %56 = OpFunctionCall %void %assign_and_preserve_padding_s %57
+         %58 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %int_1
+         %59 = OpAccessChain %_ptr_Uniform_v3half %u %uint_0
+         %60 = OpLoad %v3half %59
+               OpStore %58 %60
+         %61 = OpAccessChain %_ptr_StorageBuffer_v3half %s %uint_0 %int_1
+         %62 = OpAccessChain %_ptr_Uniform_v3half %u %uint_0
+         %63 = OpLoad %v3half %62
+         %64 = OpVectorShuffle %v3half %63 %63 2 0 1
+               OpStore %61 %64
+         %66 = OpAccessChain %_ptr_StorageBuffer_half %s %uint_0 %18 %int_1
+         %68 = OpAccessChain %_ptr_Uniform_half %u %uint_1 %21
+         %69 = OpLoad %half %68
+               OpStore %66 %69
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_storage.wgsl.expected.glsl
index 8a91538..c330038 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_storage.wgsl.expected.glsl
@@ -8,8 +8,15 @@
   mat4x3 inner;
 } s;
 
+void assign_and_preserve_padding_s(mat4x3 value) {
+  s.inner[0] = value[0u];
+  s.inner[1] = value[1u];
+  s.inner[2] = value[2u];
+  s.inner[3] = value[3u];
+}
+
 void f() {
-  s.inner = u.inner;
+  assign_and_preserve_padding_s(u.inner);
   s.inner[1] = u.inner[0];
   s.inner[1] = u.inner[0].zxy;
   s.inner[0][1] = u.inner[1][0];
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_storage.wgsl.expected.msl
index b3dcd87..82834f0 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_storage.wgsl.expected.msl
@@ -1,8 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+void assign_and_preserve_padding(device float4x3* const dest, float4x3 value) {
+  (*(dest))[0u] = value[0u];
+  (*(dest))[1u] = value[1u];
+  (*(dest))[2u] = value[2u];
+  (*(dest))[3u] = value[3u];
+}
+
 kernel void f(device float4x3* tint_symbol [[buffer(1)]], const constant float4x3* tint_symbol_1 [[buffer(0)]]) {
-  *(tint_symbol) = *(tint_symbol_1);
+  assign_and_preserve_padding(tint_symbol, *(tint_symbol_1));
   (*(tint_symbol))[1] = (*(tint_symbol_1))[0];
   (*(tint_symbol))[1] = float3((*(tint_symbol_1))[0]).zxy;
   (*(tint_symbol))[0][1] = (*(tint_symbol_1))[1][0];
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_storage.wgsl.expected.spvasm
index c6b01ce..585d88d 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 37
+; Bound: 54
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -11,6 +11,8 @@
                OpMemberName %u_block 0 "inner"
                OpName %u "u"
                OpName %s "s"
+               OpName %assign_and_preserve_padding_s "assign_and_preserve_padding_s"
+               OpName %value "value"
                OpName %f "f"
                OpDecorate %u_block Block
                OpMemberDecorate %u_block 0 Offset 0
@@ -30,36 +32,58 @@
 %_ptr_StorageBuffer_u_block = OpTypePointer StorageBuffer %u_block
           %s = OpVariable %_ptr_StorageBuffer_u_block StorageBuffer
        %void = OpTypeVoid
-          %9 = OpTypeFunction %void
+          %9 = OpTypeFunction %void %mat4v3float
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
-%_ptr_StorageBuffer_mat4v3float = OpTypePointer StorageBuffer %mat4v3float
-%_ptr_Uniform_mat4v3float = OpTypePointer Uniform %mat4v3float
         %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
+         %17 = OpConstantNull %int
 %_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
-         %24 = OpConstantNull %int
+         %20 = OpConstantNull %uint
+      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
+      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
+      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
+         %34 = OpTypeFunction %void
+%_ptr_Uniform_mat4v3float = OpTypePointer Uniform %mat4v3float
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
 %_ptr_Uniform_float = OpTypePointer Uniform %float
-          %f = OpFunction %void None %9
-         %12 = OpLabel
-         %16 = OpAccessChain %_ptr_StorageBuffer_mat4v3float %s %uint_0
-         %18 = OpAccessChain %_ptr_Uniform_mat4v3float %u %uint_0
-         %19 = OpLoad %mat4v3float %18
-               OpStore %16 %19
+%assign_and_preserve_padding_s = OpFunction %void None %9
+      %value = OpFunctionParameter %mat4v3float
+         %13 = OpLabel
+         %19 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %17
+         %21 = OpCompositeExtract %v3float %value 0
+               OpStore %19 %21
          %23 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %int_1
-         %26 = OpAccessChain %_ptr_Uniform_v3float %u %uint_0 %24
-         %27 = OpLoad %v3float %26
-               OpStore %23 %27
-         %28 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %int_1
-         %29 = OpAccessChain %_ptr_Uniform_v3float %u %uint_0 %24
-         %30 = OpLoad %v3float %29
-         %31 = OpVectorShuffle %v3float %30 %30 2 0 1
-               OpStore %28 %31
-         %33 = OpAccessChain %_ptr_StorageBuffer_float %s %uint_0 %24 %int_1
-         %35 = OpAccessChain %_ptr_Uniform_float %u %uint_0 %int_1 %24
-         %36 = OpLoad %float %35
-               OpStore %33 %36
+         %25 = OpCompositeExtract %v3float %value 1
+               OpStore %23 %25
+         %27 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %int_2
+         %29 = OpCompositeExtract %v3float %value 2
+               OpStore %27 %29
+         %31 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %int_3
+         %33 = OpCompositeExtract %v3float %value 3
+               OpStore %31 %33
+               OpReturn
+               OpFunctionEnd
+          %f = OpFunction %void None %34
+         %36 = OpLabel
+         %39 = OpAccessChain %_ptr_Uniform_mat4v3float %u %uint_0
+         %40 = OpLoad %mat4v3float %39
+         %37 = OpFunctionCall %void %assign_and_preserve_padding_s %40
+         %41 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %int_1
+         %43 = OpAccessChain %_ptr_Uniform_v3float %u %uint_0 %17
+         %44 = OpLoad %v3float %43
+               OpStore %41 %44
+         %45 = OpAccessChain %_ptr_StorageBuffer_v3float %s %uint_0 %int_1
+         %46 = OpAccessChain %_ptr_Uniform_v3float %u %uint_0 %17
+         %47 = OpLoad %v3float %46
+         %48 = OpVectorShuffle %v3float %47 %47 2 0 1
+               OpStore %45 %48
+         %50 = OpAccessChain %_ptr_StorageBuffer_float %s %uint_0 %17 %int_1
+         %52 = OpAccessChain %_ptr_Uniform_float %u %uint_0 %int_1 %17
+         %53 = OpLoad %float %52
+               OpStore %50 %53
                OpReturn
                OpFunctionEnd