msl: Implement compound assignment

Use the ExpandCompoundAssignment transform to convert compound
assignments to regular assignments.

Bug: tint:1325
Change-Id: I960bf6cd0ec3490cd58685a7c13b6a7c86395080
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/85283
Reviewed-by: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/writer/msl/generator_impl.cc b/src/tint/writer/msl/generator_impl.cc
index 07e96f2..76d19ee 100644
--- a/src/tint/writer/msl/generator_impl.cc
+++ b/src/tint/writer/msl/generator_impl.cc
@@ -61,6 +61,7 @@
 #include "src/tint/transform/array_length_from_uniform.h"
 #include "src/tint/transform/builtin_polyfill.h"
 #include "src/tint/transform/canonicalize_entry_point_io.h"
+#include "src/tint/transform/expand_compound_assignment.h"
 #include "src/tint/transform/manager.h"
 #include "src/tint/transform/module_scope_var_to_entry_point_param.h"
 #include "src/tint/transform/promote_initializers_to_const_var.h"
@@ -174,6 +175,7 @@
     manager.Add<transform::ZeroInitWorkgroupMemory>();
   }
   manager.Add<transform::CanonicalizeEntryPointIO>();
+  manager.Add<transform::ExpandCompoundAssignment>();
   manager.Add<transform::PromoteSideEffectsToDecl>();
   manager.Add<transform::UnwindDiscardFunctions>();
   manager.Add<transform::PromoteInitializersToConstVar>();
diff --git a/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.msl b/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.msl
index c7986ec..6a6d978 100644
--- a/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.msl
@@ -1,26 +1,29 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
+using namespace metal;
+struct tint_array_wrapper {
+  int4 arr[4];
+};
 
 struct S {
-  a : array<vec4<i32>, 4>,
+  tint_array_wrapper a;
+};
+
+int foo(thread int* const tint_symbol_4) {
+  *(tint_symbol_4) = as_type<int>((as_type<uint>(*(tint_symbol_4)) + as_type<uint>(1)));
+  return *(tint_symbol_4);
 }
 
-var<private> counter : i32;
-
-fn foo() -> i32 {
-  counter += 1;
-  return counter;
+int bar(thread int* const tint_symbol_5) {
+  *(tint_symbol_5) = as_type<int>((as_type<uint>(*(tint_symbol_5)) + as_type<uint>(2)));
+  return *(tint_symbol_5);
 }
 
-fn bar() -> i32 {
-  counter += 2;
-  return counter;
+void tint_symbol(thread int* const tint_symbol_6) {
+  S x = {};
+  int const tint_symbol_3 = foo(tint_symbol_6);
+  int const tint_symbol_1_save = tint_symbol_3;
+  int const tint_symbol_2 = bar(tint_symbol_6);
+  x.a.arr[tint_symbol_1_save][tint_symbol_2] = as_type<int>((as_type<uint>(x.a.arr[tint_symbol_1_save][tint_symbol_2]) + as_type<uint>(5)));
 }
 
-fn tint_symbol() {
-  var x = S();
-  let p = &(x);
-  (*(p)).a[foo()][bar()] += 5;
-}
-
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/divide_by_zero.wgsl.expected.msl b/test/tint/statements/compound_assign/divide_by_zero.wgsl.expected.msl
index eeec903..a6e7d86 100644
--- a/test/tint/statements/compound_assign/divide_by_zero.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/divide_by_zero.wgsl.expected.msl
@@ -1,19 +1,14 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
-var<private> a : i32;
-
-var<private> b : f32;
-
-fn foo(maybe_zero : i32) {
-  a /= 0;
-  a %= 0;
-  a /= maybe_zero;
-  a %= maybe_zero;
-  b /= 0.0;
-  b %= 0.0;
-  b /= f32(maybe_zero);
-  b %= f32(maybe_zero);
+using namespace metal;
+void foo(int maybe_zero, thread int* const tint_symbol, thread float* const tint_symbol_1) {
+  *(tint_symbol) = (*(tint_symbol) / 0);
+  *(tint_symbol) = (*(tint_symbol) % 0);
+  *(tint_symbol) = (*(tint_symbol) / maybe_zero);
+  *(tint_symbol) = (*(tint_symbol) % maybe_zero);
+  *(tint_symbol_1) = (*(tint_symbol_1) / 0.0f);
+  *(tint_symbol_1) = fmod(*(tint_symbol_1), 0.0f);
+  *(tint_symbol_1) = (*(tint_symbol_1) / float(maybe_zero));
+  *(tint_symbol_1) = fmod(*(tint_symbol_1), float(maybe_zero));
 }
 
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/for_loop.wgsl.expected.msl b/test/tint/statements/compound_assign/for_loop.wgsl.expected.msl
index 2903ab7..4fb8c50 100644
--- a/test/tint/statements/compound_assign/for_loop.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/for_loop.wgsl.expected.msl
@@ -1,35 +1,50 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
+using namespace metal;
 struct S {
-  a : i32,
-  b : vec4<f32>,
-  c : mat2x2<f32>,
-}
+  int a;
+  float4 b;
+  float2x2 c;
+};
 
-@group(0) @binding(0) var<storage, read_write> v : S;
-
-var<private> i : u32;
-
-fn idx1() -> i32 {
-  i += 1u;
+int idx1(thread uint* const tint_symbol_5) {
+  *(tint_symbol_5) = (*(tint_symbol_5) + 1u);
   return 1;
 }
 
-fn idx2() -> i32 {
-  i += 2u;
+int idx2(thread uint* const tint_symbol_6) {
+  *(tint_symbol_6) = (*(tint_symbol_6) + 2u);
   return 1;
 }
 
-fn idx3() -> i32 {
-  i += 3u;
+int idx3(thread uint* const tint_symbol_7) {
+  *(tint_symbol_7) = (*(tint_symbol_7) + 3u);
   return 1;
 }
 
-fn foo() {
-  var a = array<f32, 4>();
-  for(a[idx1()] *= 2.0; (a[idx2()] < 10.0); a[idx3()] += 1.0) {
+struct tint_array_wrapper {
+  float arr[4];
+};
+
+void foo(thread uint* const tint_symbol_8) {
+  tint_array_wrapper a = {.arr={}};
+  int const tint_symbol_2 = idx1(tint_symbol_8);
+  int const tint_symbol_save = tint_symbol_2;
+  {
+    a.arr[tint_symbol_save] = (a.arr[tint_symbol_save] * 2.0f);
+    while (true) {
+      int const tint_symbol_3 = idx2(tint_symbol_8);
+      if (!((a.arr[tint_symbol_3] < 10.0f))) {
+        break;
+      }
+      {
+      }
+      {
+        int const tint_symbol_4 = idx3(tint_symbol_8);
+        int const tint_symbol_1_save = tint_symbol_4;
+        a.arr[tint_symbol_1_save] = (a.arr[tint_symbol_1_save] + 1.0f);
+      }
+    }
   }
 }
 
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/function.wgsl.expected.msl b/test/tint/statements/compound_assign/function.wgsl.expected.msl
index 1d0e27a..608c013 100644
--- a/test/tint/statements/compound_assign/function.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/function.wgsl.expected.msl
@@ -1,13 +1,12 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
-fn foo() {
-  var<function> a : i32;
-  var<function> b : vec4<f32>;
-  var<function> c : mat2x2<f32>;
-  a /= 2;
-  b *= mat4x4<f32>();
-  c *= 2.0;
+using namespace metal;
+void foo() {
+  int a = 0;
+  float4 b = 0.0f;
+  float2x2 c = float2x2(0.0f);
+  a = (a / 2);
+  b = (b * float4x4());
+  c = (c * 2.0f);
 }
 
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/matrix/minus.wgsl.expected.msl b/test/tint/statements/compound_assign/matrix/minus.wgsl.expected.msl
index cbd50f8..f6fb29f 100644
--- a/test/tint/statements/compound_assign/matrix/minus.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/matrix/minus.wgsl.expected.msl
@@ -1,14 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
+using namespace metal;
 struct S {
-  a : mat4x4<f32>,
+  /* 0x0000 */ float4x4 a;
+};
+
+void foo(device S* const tint_symbol) {
+  (*(tint_symbol)).a = ((*(tint_symbol)).a - float4x4());
 }
 
-@group(0) @binding(0) var<storage, read_write> v : S;
-
-fn foo() {
-  v.a -= mat4x4<f32>();
-}
-
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/matrix/plus.wgsl.expected.msl b/test/tint/statements/compound_assign/matrix/plus.wgsl.expected.msl
index 8b7df00..7ff7cc9 100644
--- a/test/tint/statements/compound_assign/matrix/plus.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/matrix/plus.wgsl.expected.msl
@@ -1,14 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
+using namespace metal;
 struct S {
-  a : mat4x4<f32>,
+  /* 0x0000 */ float4x4 a;
+};
+
+void foo(device S* const tint_symbol) {
+  (*(tint_symbol)).a = ((*(tint_symbol)).a + float4x4());
 }
 
-@group(0) @binding(0) var<storage, read_write> v : S;
-
-fn foo() {
-  v.a += mat4x4<f32>();
-}
-
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/matrix/times-scalar.wgsl.expected.msl b/test/tint/statements/compound_assign/matrix/times-scalar.wgsl.expected.msl
index ba8ec90..900607a 100644
--- a/test/tint/statements/compound_assign/matrix/times-scalar.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/matrix/times-scalar.wgsl.expected.msl
@@ -1,14 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
+using namespace metal;
 struct S {
-  a : mat4x4<f32>,
+  /* 0x0000 */ float4x4 a;
+};
+
+void foo(device S* const tint_symbol) {
+  (*(tint_symbol)).a = ((*(tint_symbol)).a * 2.0f);
 }
 
-@group(0) @binding(0) var<storage, read_write> v : S;
-
-fn foo() {
-  v.a *= 2.0;
-}
-
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/matrix/times.wgsl.expected.msl b/test/tint/statements/compound_assign/matrix/times.wgsl.expected.msl
index ce02b88..bfce192 100644
--- a/test/tint/statements/compound_assign/matrix/times.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/matrix/times.wgsl.expected.msl
@@ -1,14 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
+using namespace metal;
 struct S {
-  a : mat4x4<f32>,
+  /* 0x0000 */ float4x4 a;
+};
+
+void foo(device S* const tint_symbol) {
+  (*(tint_symbol)).a = ((*(tint_symbol)).a * float4x4());
 }
 
-@group(0) @binding(0) var<storage, read_write> v : S;
-
-fn foo() {
-  v.a *= mat4x4<f32>();
-}
-
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/private.wgsl.expected.msl b/test/tint/statements/compound_assign/private.wgsl.expected.msl
index c655dcf..5b9bcdc 100644
--- a/test/tint/statements/compound_assign/private.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/private.wgsl.expected.msl
@@ -1,16 +1,9 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
-var<private> a : i32;
-
-var<private> b : vec4<f32>;
-
-var<private> c : mat2x2<f32>;
-
-fn foo() {
-  a /= 2;
-  b *= mat4x4<f32>();
-  c *= 2.0;
+using namespace metal;
+void foo(thread int* const tint_symbol, thread float4* const tint_symbol_1, thread float2x2* const tint_symbol_2) {
+  *(tint_symbol) = (*(tint_symbol) / 2);
+  *(tint_symbol_1) = (*(tint_symbol_1) * float4x4());
+  *(tint_symbol_2) = (*(tint_symbol_2) * 2.0f);
 }
 
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/scalar/and.wgsl.expected.msl b/test/tint/statements/compound_assign/scalar/and.wgsl.expected.msl
index 91e8f53..4ab55e2 100644
--- a/test/tint/statements/compound_assign/scalar/and.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/scalar/and.wgsl.expected.msl
@@ -1,14 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
+using namespace metal;
 struct S {
-  a : i32,
+  /* 0x0000 */ int a;
+};
+
+void foo(device S* const tint_symbol) {
+  (*(tint_symbol)).a = ((*(tint_symbol)).a & 2);
 }
 
-@group(0) @binding(0) var<storage, read_write> v : S;
-
-fn foo() {
-  v.a &= 2;
-}
-
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/scalar/divide.wgsl.expected.msl b/test/tint/statements/compound_assign/scalar/divide.wgsl.expected.msl
index d60ac98..9c19724 100644
--- a/test/tint/statements/compound_assign/scalar/divide.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/scalar/divide.wgsl.expected.msl
@@ -1,14 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
+using namespace metal;
 struct S {
-  a : i32,
+  /* 0x0000 */ int a;
+};
+
+void foo(device S* const tint_symbol) {
+  (*(tint_symbol)).a = ((*(tint_symbol)).a / 2);
 }
 
-@group(0) @binding(0) var<storage, read_write> v : S;
-
-fn foo() {
-  v.a /= 2;
-}
-
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/scalar/minus.wgsl.expected.msl b/test/tint/statements/compound_assign/scalar/minus.wgsl.expected.msl
index e091f6c..edad8ea 100644
--- a/test/tint/statements/compound_assign/scalar/minus.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/scalar/minus.wgsl.expected.msl
@@ -1,14 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
+using namespace metal;
 struct S {
-  a : i32,
+  /* 0x0000 */ int a;
+};
+
+void foo(device S* const tint_symbol) {
+  (*(tint_symbol)).a = as_type<int>((as_type<uint>((*(tint_symbol)).a) - as_type<uint>(2)));
 }
 
-@group(0) @binding(0) var<storage, read_write> v : S;
-
-fn foo() {
-  v.a -= 2;
-}
-
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/scalar/modulo.wgsl.expected.msl b/test/tint/statements/compound_assign/scalar/modulo.wgsl.expected.msl
index 4d04799..74cbbf7 100644
--- a/test/tint/statements/compound_assign/scalar/modulo.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/scalar/modulo.wgsl.expected.msl
@@ -1,14 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
+using namespace metal;
 struct S {
-  a : i32,
+  /* 0x0000 */ int a;
+};
+
+void foo(device S* const tint_symbol) {
+  (*(tint_symbol)).a = ((*(tint_symbol)).a % 2);
 }
 
-@group(0) @binding(0) var<storage, read_write> v : S;
-
-fn foo() {
-  v.a %= 2;
-}
-
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/scalar/or.wgsl.expected.msl b/test/tint/statements/compound_assign/scalar/or.wgsl.expected.msl
index eab9b3b..d283099 100644
--- a/test/tint/statements/compound_assign/scalar/or.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/scalar/or.wgsl.expected.msl
@@ -1,14 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
+using namespace metal;
 struct S {
-  a : i32,
+  /* 0x0000 */ int a;
+};
+
+void foo(device S* const tint_symbol) {
+  (*(tint_symbol)).a = ((*(tint_symbol)).a | 2);
 }
 
-@group(0) @binding(0) var<storage, read_write> v : S;
-
-fn foo() {
-  v.a |= 2;
-}
-
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/scalar/plus.wgsl.expected.msl b/test/tint/statements/compound_assign/scalar/plus.wgsl.expected.msl
index 614eba8..2b9a245 100644
--- a/test/tint/statements/compound_assign/scalar/plus.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/scalar/plus.wgsl.expected.msl
@@ -1,14 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
+using namespace metal;
 struct S {
-  a : i32,
+  /* 0x0000 */ int a;
+};
+
+void foo(device S* const tint_symbol) {
+  (*(tint_symbol)).a = as_type<int>((as_type<uint>((*(tint_symbol)).a) + as_type<uint>(2)));
 }
 
-@group(0) @binding(0) var<storage, read_write> v : S;
-
-fn foo() {
-  v.a += 2;
-}
-
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/scalar/times.wgsl.expected.msl b/test/tint/statements/compound_assign/scalar/times.wgsl.expected.msl
index fb265ff..b3da015 100644
--- a/test/tint/statements/compound_assign/scalar/times.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/scalar/times.wgsl.expected.msl
@@ -1,14 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
+using namespace metal;
 struct S {
-  a : i32,
+  /* 0x0000 */ int a;
+};
+
+void foo(device S* const tint_symbol) {
+  (*(tint_symbol)).a = as_type<int>((as_type<uint>((*(tint_symbol)).a) * as_type<uint>(2)));
 }
 
-@group(0) @binding(0) var<storage, read_write> v : S;
-
-fn foo() {
-  v.a *= 2;
-}
-
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/scalar/xor.wgsl.expected.msl b/test/tint/statements/compound_assign/scalar/xor.wgsl.expected.msl
index 4113428..80a265d 100644
--- a/test/tint/statements/compound_assign/scalar/xor.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/scalar/xor.wgsl.expected.msl
@@ -1,14 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
+using namespace metal;
 struct S {
-  a : i32,
+  /* 0x0000 */ int a;
+};
+
+void foo(device S* const tint_symbol) {
+  (*(tint_symbol)).a = ((*(tint_symbol)).a ^ 2);
 }
 
-@group(0) @binding(0) var<storage, read_write> v : S;
-
-fn foo() {
-  v.a ^= 2;
-}
-
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/vector/and.wgsl.expected.msl b/test/tint/statements/compound_assign/vector/and.wgsl.expected.msl
index 61074a2..937169f 100644
--- a/test/tint/statements/compound_assign/vector/and.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/vector/and.wgsl.expected.msl
@@ -1,14 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
+using namespace metal;
 struct S {
-  a : vec4<i32>,
+  /* 0x0000 */ int4 a;
+};
+
+void foo(device S* const tint_symbol) {
+  (*(tint_symbol)).a = ((*(tint_symbol)).a & int4(2));
 }
 
-@group(0) @binding(0) var<storage, read_write> v : S;
-
-fn foo() {
-  v.a &= vec4<i32>(2);
-}
-
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/vector/divide-scalar.wgsl.expected.msl b/test/tint/statements/compound_assign/vector/divide-scalar.wgsl.expected.msl
index 1d24582..76b8f1f 100644
--- a/test/tint/statements/compound_assign/vector/divide-scalar.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/vector/divide-scalar.wgsl.expected.msl
@@ -1,14 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
+using namespace metal;
 struct S {
-  a : vec4<f32>,
+  /* 0x0000 */ float4 a;
+};
+
+void foo(device S* const tint_symbol) {
+  (*(tint_symbol)).a = ((*(tint_symbol)).a / 2.0f);
 }
 
-@group(0) @binding(0) var<storage, read_write> v : S;
-
-fn foo() {
-  v.a /= 2.0;
-}
-
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/vector/divide.wgsl.expected.msl b/test/tint/statements/compound_assign/vector/divide.wgsl.expected.msl
index 817a93c..ace4828 100644
--- a/test/tint/statements/compound_assign/vector/divide.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/vector/divide.wgsl.expected.msl
@@ -1,14 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
+using namespace metal;
 struct S {
-  a : vec4<i32>,
+  /* 0x0000 */ int4 a;
+};
+
+void foo(device S* const tint_symbol) {
+  (*(tint_symbol)).a = ((*(tint_symbol)).a / int4(2));
 }
 
-@group(0) @binding(0) var<storage, read_write> v : S;
-
-fn foo() {
-  v.a /= vec4<i32>(2);
-}
-
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/vector/minus-scalar.wgsl.expected.msl b/test/tint/statements/compound_assign/vector/minus-scalar.wgsl.expected.msl
index d8d8f2c..3b7c317 100644
--- a/test/tint/statements/compound_assign/vector/minus-scalar.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/vector/minus-scalar.wgsl.expected.msl
@@ -1,14 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
+using namespace metal;
 struct S {
-  a : vec4<f32>,
+  /* 0x0000 */ float4 a;
+};
+
+void foo(device S* const tint_symbol) {
+  (*(tint_symbol)).a = ((*(tint_symbol)).a - 2.0f);
 }
 
-@group(0) @binding(0) var<storage, read_write> v : S;
-
-fn foo() {
-  v.a -= 2.0;
-}
-
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/vector/minus.wgsl.expected.msl b/test/tint/statements/compound_assign/vector/minus.wgsl.expected.msl
index ae94d7f..1a225d3 100644
--- a/test/tint/statements/compound_assign/vector/minus.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/vector/minus.wgsl.expected.msl
@@ -1,14 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
+using namespace metal;
 struct S {
-  a : vec4<i32>,
+  /* 0x0000 */ int4 a;
+};
+
+void foo(device S* const tint_symbol) {
+  (*(tint_symbol)).a = as_type<int4>((as_type<uint4>((*(tint_symbol)).a) - as_type<uint4>(int4(2))));
 }
 
-@group(0) @binding(0) var<storage, read_write> v : S;
-
-fn foo() {
-  v.a -= vec4<i32>(2);
-}
-
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/vector/modulo-scalar.wgsl.expected.msl b/test/tint/statements/compound_assign/vector/modulo-scalar.wgsl.expected.msl
index c4ca605..697323b 100644
--- a/test/tint/statements/compound_assign/vector/modulo-scalar.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/vector/modulo-scalar.wgsl.expected.msl
@@ -1,14 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
+using namespace metal;
 struct S {
-  a : vec4<i32>,
+  /* 0x0000 */ int4 a;
+};
+
+void foo(device S* const tint_symbol) {
+  (*(tint_symbol)).a = ((*(tint_symbol)).a % 2);
 }
 
-@group(0) @binding(0) var<storage, read_write> v : S;
-
-fn foo() {
-  v.a %= 2;
-}
-
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/vector/modulo.wgsl.expected.msl b/test/tint/statements/compound_assign/vector/modulo.wgsl.expected.msl
index 1574ee9..fafddb8 100644
--- a/test/tint/statements/compound_assign/vector/modulo.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/vector/modulo.wgsl.expected.msl
@@ -1,14 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
+using namespace metal;
 struct S {
-  a : vec4<i32>,
+  /* 0x0000 */ int4 a;
+};
+
+void foo(device S* const tint_symbol) {
+  (*(tint_symbol)).a = ((*(tint_symbol)).a % int4(2));
 }
 
-@group(0) @binding(0) var<storage, read_write> v : S;
-
-fn foo() {
-  v.a %= vec4<i32>(2);
-}
-
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/vector/or.wgsl.expected.msl b/test/tint/statements/compound_assign/vector/or.wgsl.expected.msl
index 95ac3ab..092fb1f 100644
--- a/test/tint/statements/compound_assign/vector/or.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/vector/or.wgsl.expected.msl
@@ -1,14 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
+using namespace metal;
 struct S {
-  a : vec4<i32>,
+  /* 0x0000 */ int4 a;
+};
+
+void foo(device S* const tint_symbol) {
+  (*(tint_symbol)).a = ((*(tint_symbol)).a | int4(2));
 }
 
-@group(0) @binding(0) var<storage, read_write> v : S;
-
-fn foo() {
-  v.a |= vec4<i32>(2);
-}
-
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/vector/plus-scalar.wgsl.expected.msl b/test/tint/statements/compound_assign/vector/plus-scalar.wgsl.expected.msl
index 1d292d8..7296109 100644
--- a/test/tint/statements/compound_assign/vector/plus-scalar.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/vector/plus-scalar.wgsl.expected.msl
@@ -1,14 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
+using namespace metal;
 struct S {
-  a : vec4<f32>,
+  /* 0x0000 */ float4 a;
+};
+
+void foo(device S* const tint_symbol) {
+  (*(tint_symbol)).a = ((*(tint_symbol)).a + 2.0f);
 }
 
-@group(0) @binding(0) var<storage, read_write> v : S;
-
-fn foo() {
-  v.a += 2.0;
-}
-
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/vector/plus.wgsl.expected.msl b/test/tint/statements/compound_assign/vector/plus.wgsl.expected.msl
index db5b583..7ea366b 100644
--- a/test/tint/statements/compound_assign/vector/plus.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/vector/plus.wgsl.expected.msl
@@ -1,14 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
+using namespace metal;
 struct S {
-  a : vec4<i32>,
+  /* 0x0000 */ int4 a;
+};
+
+void foo(device S* const tint_symbol) {
+  (*(tint_symbol)).a = as_type<int4>((as_type<uint4>((*(tint_symbol)).a) + as_type<uint4>(int4(2))));
 }
 
-@group(0) @binding(0) var<storage, read_write> v : S;
-
-fn foo() {
-  v.a += vec4<i32>(2);
-}
-
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/vector/times-matrix.wgsl.expected.msl b/test/tint/statements/compound_assign/vector/times-matrix.wgsl.expected.msl
index f9b30dd..b7722c8 100644
--- a/test/tint/statements/compound_assign/vector/times-matrix.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/vector/times-matrix.wgsl.expected.msl
@@ -1,14 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
+using namespace metal;
 struct S {
-  a : vec4<f32>,
+  /* 0x0000 */ float4 a;
+};
+
+void foo(device S* const tint_symbol) {
+  (*(tint_symbol)).a = ((*(tint_symbol)).a * float4x4());
 }
 
-@group(0) @binding(0) var<storage, read_write> v : S;
-
-fn foo() {
-  v.a *= mat4x4<f32>();
-}
-
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/vector/times-scalar.wgsl.expected.msl b/test/tint/statements/compound_assign/vector/times-scalar.wgsl.expected.msl
index eac3281..dcb841b 100644
--- a/test/tint/statements/compound_assign/vector/times-scalar.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/vector/times-scalar.wgsl.expected.msl
@@ -1,14 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
+using namespace metal;
 struct S {
-  a : vec4<f32>,
+  /* 0x0000 */ float4 a;
+};
+
+void foo(device S* const tint_symbol) {
+  (*(tint_symbol)).a = ((*(tint_symbol)).a * 2.0f);
 }
 
-@group(0) @binding(0) var<storage, read_write> v : S;
-
-fn foo() {
-  v.a *= 2.0;
-}
-
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/vector/times.wgsl.expected.msl b/test/tint/statements/compound_assign/vector/times.wgsl.expected.msl
index a486a56..ef7fd06 100644
--- a/test/tint/statements/compound_assign/vector/times.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/vector/times.wgsl.expected.msl
@@ -1,14 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
+using namespace metal;
 struct S {
-  a : vec4<i32>,
+  /* 0x0000 */ int4 a;
+};
+
+void foo(device S* const tint_symbol) {
+  (*(tint_symbol)).a = as_type<int4>((as_type<uint4>((*(tint_symbol)).a) * as_type<uint4>(int4(2))));
 }
 
-@group(0) @binding(0) var<storage, read_write> v : S;
-
-fn foo() {
-  v.a *= vec4<i32>(2);
-}
-
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/vector/xor.wgsl.expected.msl b/test/tint/statements/compound_assign/vector/xor.wgsl.expected.msl
index 2ce3277..f82f4d9 100644
--- a/test/tint/statements/compound_assign/vector/xor.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/vector/xor.wgsl.expected.msl
@@ -1,14 +1,11 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
+using namespace metal;
 struct S {
-  a : vec4<i32>,
+  /* 0x0000 */ int4 a;
+};
+
+void foo(device S* const tint_symbol) {
+  (*(tint_symbol)).a = ((*(tint_symbol)).a ^ int4(2));
 }
 
-@group(0) @binding(0) var<storage, read_write> v : S;
-
-fn foo() {
-  v.a ^= vec4<i32>(2);
-}
-
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement
diff --git a/test/tint/statements/compound_assign/workgroup.wgsl.expected.msl b/test/tint/statements/compound_assign/workgroup.wgsl.expected.msl
index 5cdf29f..14ce2d4 100644
--- a/test/tint/statements/compound_assign/workgroup.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/workgroup.wgsl.expected.msl
@@ -1,16 +1,9 @@
-SKIP: FAILED
+#include <metal_stdlib>
 
-
-var<workgroup> a : i32;
-
-var<workgroup> b : vec4<f32>;
-
-var<workgroup> c : mat2x2<f32>;
-
-fn foo() {
-  a /= 2;
-  b *= mat4x4<f32>();
-  c *= 2.0;
+using namespace metal;
+void foo(threadgroup int* const tint_symbol, threadgroup float4* const tint_symbol_1, threadgroup float2x2* const tint_symbol_2) {
+  *(tint_symbol) = (*(tint_symbol) / 2);
+  *(tint_symbol_1) = (*(tint_symbol_1) * float4x4());
+  *(tint_symbol_2) = (*(tint_symbol_2) * 2.0f);
 }
 
-Failed to generate: error: unknown statement type: tint::ast::CompoundAssignmentStatement