[msl] Add support for most atomic builtins

Define MSL intrinsics for them and add a new MemoryOrder constant so
that the printer can emit memory_order enum values.

Bug: 42251016
Change-Id: I36d52c15c5bb0cd424b16fdf733a4f1df3364f4a
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/191662
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/tint/lang/core/ir/builder.h b/src/tint/lang/core/ir/builder.h
index 9e4f75e..7a33fd9 100644
--- a/src/tint/lang/core/ir/builder.h
+++ b/src/tint/lang/core/ir/builder.h
@@ -66,7 +66,7 @@
 #include "src/tint/lang/core/ir/terminate_invocation.h"
 #include "src/tint/lang/core/ir/unreachable.h"
 #include "src/tint/lang/core/ir/user_call.h"
-#include "src/tint/lang/core/ir/value.h"
+#include "src/tint/lang/core/ir/value.h"  // IWYU pragma: export
 #include "src/tint/lang/core/ir/var.h"
 #include "src/tint/lang/core/type/array.h"  // IWYU pragma: export
 #include "src/tint/lang/core/type/bool.h"   // IWYU pragma: export
diff --git a/src/tint/lang/msl/builtin_fn.cc b/src/tint/lang/msl/builtin_fn.cc
index 18d96de..ec0fc13 100644
--- a/src/tint/lang/msl/builtin_fn.cc
+++ b/src/tint/lang/msl/builtin_fn.cc
@@ -42,6 +42,26 @@
     switch (i) {
         case BuiltinFn::kNone:
             return "<none>";
+        case BuiltinFn::kAtomicExchangeExplicit:
+            return "atomic_exchange_explicit";
+        case BuiltinFn::kAtomicFetchAddExplicit:
+            return "atomic_fetch_add_explicit";
+        case BuiltinFn::kAtomicFetchAndExplicit:
+            return "atomic_fetch_and_explicit";
+        case BuiltinFn::kAtomicFetchMaxExplicit:
+            return "atomic_fetch_max_explicit";
+        case BuiltinFn::kAtomicFetchMinExplicit:
+            return "atomic_fetch_min_explicit";
+        case BuiltinFn::kAtomicFetchOrExplicit:
+            return "atomic_fetch_or_explicit";
+        case BuiltinFn::kAtomicFetchSubExplicit:
+            return "atomic_fetch_sub_explicit";
+        case BuiltinFn::kAtomicFetchXorExplicit:
+            return "atomic_fetch_xor_explicit";
+        case BuiltinFn::kAtomicLoadExplicit:
+            return "atomic_load_explicit";
+        case BuiltinFn::kAtomicStoreExplicit:
+            return "atomic_store_explicit";
         case BuiltinFn::kThreadgroupBarrier:
             return "threadgroup_barrier";
     }
diff --git a/src/tint/lang/msl/builtin_fn.h b/src/tint/lang/msl/builtin_fn.h
index c652488..0c42779 100644
--- a/src/tint/lang/msl/builtin_fn.h
+++ b/src/tint/lang/msl/builtin_fn.h
@@ -47,6 +47,16 @@
 
 /// Enumerator of all builtin functions
 enum class BuiltinFn : uint8_t {
+    kAtomicExchangeExplicit,
+    kAtomicFetchAddExplicit,
+    kAtomicFetchAndExplicit,
+    kAtomicFetchMaxExplicit,
+    kAtomicFetchMinExplicit,
+    kAtomicFetchOrExplicit,
+    kAtomicFetchSubExplicit,
+    kAtomicFetchXorExplicit,
+    kAtomicLoadExplicit,
+    kAtomicStoreExplicit,
     kThreadgroupBarrier,
     kNone,
 };
diff --git a/src/tint/lang/msl/intrinsic/data.cc b/src/tint/lang/msl/intrinsic/data.cc
index 3baa716..61246ec 100644
--- a/src/tint/lang/msl/intrinsic/data.cc
+++ b/src/tint/lang/msl/intrinsic/data.cc
@@ -74,6 +74,20 @@
 
 // clang-format off
 
+/// TypeMatcher for 'type i32'
+constexpr TypeMatcher kI32Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+    if (!MatchI32(state, ty)) {
+      return nullptr;
+    }
+    return BuildI32(state, ty);
+  },
+/* print */ []([[maybe_unused]] MatchState* state, StyledText& out) {
+    out << style::Type("i32");
+  }
+};
+
+
 /// TypeMatcher for 'type u32'
 constexpr TypeMatcher kU32Matcher {
 /* match */ [](MatchState& state, const Type* ty) -> const Type* {
@@ -88,15 +102,133 @@
 };
 
 
+/// TypeMatcher for 'type atomic'
+constexpr TypeMatcher kAtomicMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+  const Type* T = nullptr;
+    if (!MatchAtomic(state, ty, T)) {
+      return nullptr;
+    }
+    T = state.Type(T);
+    if (T == nullptr) {
+      return nullptr;
+    }
+    return BuildAtomic(state, ty, T);
+  },
+/* print */ []([[maybe_unused]] MatchState* state, StyledText& out) {StyledText T;
+  state->PrintType(T);
+    out << style::Type("atomic", "<", T, ">");
+  }
+};
+
+
+/// TypeMatcher for 'type ptr'
+constexpr TypeMatcher kPtrMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+  Number S = Number::invalid;
+  const Type* T = nullptr;
+  Number A = Number::invalid;
+    if (!MatchPtr(state, ty, S, T, A)) {
+      return nullptr;
+    }
+    S = state.Num(S);
+    if (!S.IsValid()) {
+      return nullptr;
+    }
+    T = state.Type(T);
+    if (T == nullptr) {
+      return nullptr;
+    }
+    A = state.Num(A);
+    if (!A.IsValid()) {
+      return nullptr;
+    }
+    return BuildPtr(state, ty, S, T, A);
+  },
+/* print */ []([[maybe_unused]] MatchState* state, StyledText& out) {StyledText S;
+  state->PrintNum(S);StyledText T;
+  state->PrintType(T);StyledText A;
+  state->PrintNum(A);
+    out << style::Type("ptr", "<", S, ", ", T, ", ", A, ">");
+  }
+};
+
+
+/// TypeMatcher for 'match iu32'
+constexpr TypeMatcher kIu32Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+    if (MatchI32(state, ty)) {
+      return BuildI32(state, ty);
+    }
+    if (MatchU32(state, ty)) {
+      return BuildU32(state, ty);
+    }
+    return nullptr;
+  },
+/* print */ [](MatchState*, StyledText& out) {
+    // Note: We pass nullptr to the Matcher.print() functions, as matchers do not support
+    // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
+ kI32Matcher.print(nullptr, out); out << style::Plain(" or "); kU32Matcher.print(nullptr, out);}
+};
+
+/// EnumMatcher for 'match read_write'
+constexpr NumberMatcher kReadWriteMatcher {
+/* match */ [](MatchState&, Number number) -> Number {
+    if (number.IsAny() || number.Value() == static_cast<uint32_t>(core::Access::kReadWrite)) {
+      return Number(static_cast<uint32_t>(core::Access::kReadWrite));
+    }
+    return Number::invalid;
+  },
+/* print */ [](MatchState*, StyledText& out) {
+  out<< style::Enum("read_write");
+  }
+};
+
+/// EnumMatcher for 'match workgroup_or_storage'
+constexpr NumberMatcher kWorkgroupOrStorageMatcher {
+/* match */ [](MatchState&, Number number) -> Number {
+    switch (static_cast<core::AddressSpace>(number.Value())) {
+      case core::AddressSpace::kWorkgroup:
+      case core::AddressSpace::kStorage:
+        return number;
+      default:
+        return Number::invalid;
+    }
+  },
+/* print */ [](MatchState*, StyledText& out) {
+  out<< style::Enum("workgroup")<< style::Plain(" or ") << style::Enum("storage");
+  }
+};
+
 /// Type and number matchers
 
 /// The template types, types, and type matchers
 constexpr TypeMatcher kTypeMatchers[] = {
-  /* [0] */ kU32Matcher,
+  /* [0] */ TemplateTypeMatcher<0>::matcher,
+  /* [1] */ TemplateTypeMatcher<1>::matcher,
+  /* [2] */ kI32Matcher,
+  /* [3] */ kU32Matcher,
+  /* [4] */ kAtomicMatcher,
+  /* [5] */ kPtrMatcher,
+  /* [6] */ kIu32Matcher,
+};
+
+/// The template numbers, and number matchers
+constexpr NumberMatcher kNumberMatchers[] = {
+  /* [0] */ TemplateNumberMatcher<0>::matcher,
+  /* [1] */ TemplateNumberMatcher<1>::matcher,
+  /* [2] */ kReadWriteMatcher,
+  /* [3] */ kWorkgroupOrStorageMatcher,
 };
 
 constexpr MatcherIndex kMatcherIndices[] = {
-  /* [0] */ MatcherIndex(0),
+  /* [0] */ MatcherIndex(5),
+  /* [1] */ MatcherIndex(1),
+  /* [2] */ MatcherIndex(4),
+  /* [3] */ MatcherIndex(0),
+  /* [4] */ MatcherIndex(2),
+  /* [5] */ MatcherIndex(6),
+  /* [6] */ MatcherIndex(3),
 };
 
 static_assert(MatcherIndicesIndex::CanIndex(kMatcherIndices),
@@ -108,20 +240,91 @@
     /* usage */ core::ParameterUsage::kNone,
     /* matcher_indices */ MatcherIndicesIndex(0),
   },
+  {
+    /* [1] */
+    /* usage */ core::ParameterUsage::kNone,
+    /* matcher_indices */ MatcherIndicesIndex(3),
+  },
+  {
+    /* [2] */
+    /* usage */ core::ParameterUsage::kNone,
+    /* matcher_indices */ MatcherIndicesIndex(6),
+  },
+  {
+    /* [3] */
+    /* usage */ core::ParameterUsage::kNone,
+    /* matcher_indices */ MatcherIndicesIndex(0),
+  },
+  {
+    /* [4] */
+    /* usage */ core::ParameterUsage::kNone,
+    /* matcher_indices */ MatcherIndicesIndex(6),
+  },
 };
 
 static_assert(ParameterIndex::CanIndex(kParameters),
               "ParameterIndex is not large enough to index kParameters");
 
+constexpr TemplateInfo kTemplates[] = {
+  {
+    /* [0] */
+    /* name */ "T",
+    /* matcher_indices */ MatcherIndicesIndex(5),
+    /* kind */ TemplateInfo::Kind::kType,
+  },
+  {
+    /* [1] */
+    /* name */ "S",
+    /* matcher_indices */ MatcherIndicesIndex(6),
+    /* kind */ TemplateInfo::Kind::kNumber,
+  },
+};
+
+static_assert(TemplateIndex::CanIndex(kTemplates),
+              "TemplateIndex is not large enough to index kTemplates");
+
 constexpr OverloadInfo kOverloads[] = {
   {
     /* [0] */
+    /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+    /* num_parameters */ 3,
+    /* num_explicit_templates */ 0,
+    /* num_templates   */ 2,
+    /* templates */ TemplateIndex(0),
+    /* parameters */ ParameterIndex(0),
+    /* return_matcher_indices */ MatcherIndicesIndex(3),
+    /* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
+  },
+  {
+    /* [1] */
+    /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+    /* num_parameters */ 2,
+    /* num_explicit_templates */ 0,
+    /* num_templates   */ 2,
+    /* templates */ TemplateIndex(0),
+    /* parameters */ ParameterIndex(3),
+    /* return_matcher_indices */ MatcherIndicesIndex(3),
+    /* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
+  },
+  {
+    /* [2] */
+    /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+    /* num_parameters */ 3,
+    /* num_explicit_templates */ 0,
+    /* num_templates   */ 2,
+    /* templates */ TemplateIndex(0),
+    /* parameters */ ParameterIndex(0),
+    /* return_matcher_indices */ MatcherIndicesIndex(/* invalid */),
+    /* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
+  },
+  {
+    /* [3] */
     /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsComputePipeline),
     /* num_parameters */ 1,
     /* num_explicit_templates */ 0,
     /* num_templates   */ 0,
     /* templates */ TemplateIndex(/* invalid */),
-    /* parameters */ ParameterIndex(0),
+    /* parameters */ ParameterIndex(2),
     /* return_matcher_indices */ MatcherIndicesIndex(/* invalid */),
     /* const_eval_fn */ ConstEvalFunctionIndex(/* invalid */),
   },
@@ -133,10 +336,70 @@
 constexpr IntrinsicInfo kBuiltins[] = {
   {
     /* [0] */
-    /* fn threadgroup_barrier(u32) */
+    /* fn atomic_exchange_explicit[T : iu32, S : workgroup_or_storage](ptr<S, atomic<T>, read_write>, T, u32) -> T */
     /* num overloads */ 1,
     /* overloads */ OverloadIndex(0),
   },
+  {
+    /* [1] */
+    /* fn atomic_fetch_add_explicit[T : iu32, S : workgroup_or_storage](ptr<S, atomic<T>, read_write>, T, u32) -> T */
+    /* num overloads */ 1,
+    /* overloads */ OverloadIndex(0),
+  },
+  {
+    /* [2] */
+    /* fn atomic_fetch_and_explicit[T : iu32, S : workgroup_or_storage](ptr<S, atomic<T>, read_write>, T, u32) -> T */
+    /* num overloads */ 1,
+    /* overloads */ OverloadIndex(0),
+  },
+  {
+    /* [3] */
+    /* fn atomic_fetch_max_explicit[T : iu32, S : workgroup_or_storage](ptr<S, atomic<T>, read_write>, T, u32) -> T */
+    /* num overloads */ 1,
+    /* overloads */ OverloadIndex(0),
+  },
+  {
+    /* [4] */
+    /* fn atomic_fetch_min_explicit[T : iu32, S : workgroup_or_storage](ptr<S, atomic<T>, read_write>, T, u32) -> T */
+    /* num overloads */ 1,
+    /* overloads */ OverloadIndex(0),
+  },
+  {
+    /* [5] */
+    /* fn atomic_fetch_or_explicit[T : iu32, S : workgroup_or_storage](ptr<S, atomic<T>, read_write>, T, u32) -> T */
+    /* num overloads */ 1,
+    /* overloads */ OverloadIndex(0),
+  },
+  {
+    /* [6] */
+    /* fn atomic_fetch_sub_explicit[T : iu32, S : workgroup_or_storage](ptr<S, atomic<T>, read_write>, T, u32) -> T */
+    /* num overloads */ 1,
+    /* overloads */ OverloadIndex(0),
+  },
+  {
+    /* [7] */
+    /* fn atomic_fetch_xor_explicit[T : iu32, S : workgroup_or_storage](ptr<S, atomic<T>, read_write>, T, u32) -> T */
+    /* num overloads */ 1,
+    /* overloads */ OverloadIndex(0),
+  },
+  {
+    /* [8] */
+    /* fn atomic_load_explicit[T : iu32, S : workgroup_or_storage](ptr<S, atomic<T>, read_write>, u32) -> T */
+    /* num overloads */ 1,
+    /* overloads */ OverloadIndex(1),
+  },
+  {
+    /* [9] */
+    /* fn atomic_store_explicit[T : iu32, S : workgroup_or_storage](ptr<S, atomic<T>, read_write>, T, u32) */
+    /* num overloads */ 1,
+    /* overloads */ OverloadIndex(2),
+  },
+  {
+    /* [10] */
+    /* fn threadgroup_barrier(u32) */
+    /* num overloads */ 1,
+    /* overloads */ OverloadIndex(3),
+  },
 };
 
 // clang-format on
@@ -144,10 +407,10 @@
 }  // anonymous namespace
 
 const core::intrinsic::TableData Dialect::kData{
-    /* templates */ Empty,
+    /* templates */ kTemplates,
     /* type_matcher_indices */ kMatcherIndices,
     /* type_matchers */ kTypeMatchers,
-    /* number_matchers */ Empty,
+    /* number_matchers */ kNumberMatchers,
     /* parameters */ kParameters,
     /* overloads */ kOverloads,
     /* const_eval_functions */ Empty,
diff --git a/src/tint/lang/msl/ir/BUILD.bazel b/src/tint/lang/msl/ir/BUILD.bazel
index cff7707..d7f52b8 100644
--- a/src/tint/lang/msl/ir/BUILD.bazel
+++ b/src/tint/lang/msl/ir/BUILD.bazel
@@ -40,9 +40,11 @@
   name = "ir",
   srcs = [
     "builtin_call.cc",
+    "memory_order.cc",
   ],
   hdrs = [
     "builtin_call.h",
+    "memory_order.h",
   ],
   deps = [
     "//src/tint/api/common",
diff --git a/src/tint/lang/msl/ir/BUILD.cmake b/src/tint/lang/msl/ir/BUILD.cmake
index 1f4769d..1ff9a0c 100644
--- a/src/tint/lang/msl/ir/BUILD.cmake
+++ b/src/tint/lang/msl/ir/BUILD.cmake
@@ -41,6 +41,8 @@
 tint_add_target(tint_lang_msl_ir lib
   lang/msl/ir/builtin_call.cc
   lang/msl/ir/builtin_call.h
+  lang/msl/ir/memory_order.cc
+  lang/msl/ir/memory_order.h
 )
 
 tint_target_add_dependencies(tint_lang_msl_ir lib
diff --git a/src/tint/lang/msl/ir/BUILD.gn b/src/tint/lang/msl/ir/BUILD.gn
index a072d1c..21fb844 100644
--- a/src/tint/lang/msl/ir/BUILD.gn
+++ b/src/tint/lang/msl/ir/BUILD.gn
@@ -46,6 +46,8 @@
   sources = [
     "builtin_call.cc",
     "builtin_call.h",
+    "memory_order.cc",
+    "memory_order.h",
   ]
   deps = [
     "${tint_src_dir}/api/common",
diff --git a/src/tint/lang/msl/ir/memory_order.cc b/src/tint/lang/msl/ir/memory_order.cc
new file mode 100644
index 0000000..03e61ee
--- /dev/null
+++ b/src/tint/lang/msl/ir/memory_order.cc
@@ -0,0 +1,41 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+//    contributors may be used to endorse or promote products derived from
+//    this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "src/tint/lang/msl/ir/memory_order.h"
+
+#include "src/tint/lang/core/constant/value.h"
+#include "src/tint/utils/rtti/castable.h"
+
+TINT_INSTANTIATE_TYPEINFO(tint::msl::ir::MemoryOrder);
+
+namespace tint::msl::ir {
+
+MemoryOrder::MemoryOrder(const core::constant::Value* value) : Base(value) {}
+
+MemoryOrder::~MemoryOrder() = default;
+
+}  // namespace tint::msl::ir
diff --git a/src/tint/lang/msl/ir/memory_order.h b/src/tint/lang/msl/ir/memory_order.h
new file mode 100644
index 0000000..d0b120e
--- /dev/null
+++ b/src/tint/lang/msl/ir/memory_order.h
@@ -0,0 +1,49 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+//    contributors may be used to endorse or promote products derived from
+//    this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef SRC_TINT_LANG_MSL_IR_MEMORY_ORDER_H_
+#define SRC_TINT_LANG_MSL_IR_MEMORY_ORDER_H_
+
+#include "src/tint/lang/core/ir/constant.h"
+#include "src/tint/utils/rtti/castable.h"
+
+namespace tint::msl::ir {
+
+/// MemoryOrder is a type of constant value that is intended to be emitted as a memory_order enum
+/// value by the MSL printer.
+class MemoryOrder final : public Castable<MemoryOrder, core::ir::Constant> {
+  public:
+    /// Constructor
+    /// @param value the operand value
+    explicit MemoryOrder(const core::constant::Value* value);
+    /// Destructor
+    ~MemoryOrder() override;
+};
+
+}  // namespace tint::msl::ir
+
+#endif  // SRC_TINT_LANG_MSL_IR_MEMORY_ORDER_H_
diff --git a/src/tint/lang/msl/msl.def b/src/tint/lang/msl/msl.def
index 92e7aa6..324e299 100644
--- a/src/tint/lang/msl/msl.def
+++ b/src/tint/lang/msl/msl.def
@@ -35,10 +35,46 @@
 // See docs/tint/intrinsic_definition_files.md for syntax                     //
 ////////////////////////////////////////////////////////////////////////////////
 
+import "src/tint/lang/core/access.def"
+import "src/tint/lang/core/address_space.def"
+
+////////////////////////////////////////////////////////////////////////////////
+// Enum matchers                                                              //
+////////////////////////////////////////////////////////////////////////////////
+
+match read_write: access.read_write
+
+match workgroup_or_storage
+  : address_space.workgroup
+  | address_space.storage
+
+////////////////////////////////////////////////////////////////////////////////
+// Types                                                                      //
+////////////////////////////////////////////////////////////////////////////////
+
+type i32
 type u32
+type atomic<T>
+type ptr<S: address_space, T, A: access>
+
+////////////////////////////////////////////////////////////////////////////////
+// Type matchers                                                              //
+////////////////////////////////////////////////////////////////////////////////
+
+match iu32: i32 | u32
 
 ////////////////////////////////////////////////////////////////////////////////
 // Builtin Functions                                                          //
 ////////////////////////////////////////////////////////////////////////////////
+@stage("fragment", "compute") fn atomic_exchange_explicit[T: iu32, S: workgroup_or_storage](ptr<S, atomic<T>, read_write>, T, u32) -> T
+@stage("fragment", "compute") fn atomic_fetch_add_explicit[T: iu32, S: workgroup_or_storage](ptr<S, atomic<T>, read_write>, T, u32) -> T
+@stage("fragment", "compute") fn atomic_fetch_and_explicit[T: iu32, S: workgroup_or_storage](ptr<S, atomic<T>, read_write>, T, u32) -> T
+@stage("fragment", "compute") fn atomic_fetch_max_explicit[T: iu32, S: workgroup_or_storage](ptr<S, atomic<T>, read_write>, T, u32) -> T
+@stage("fragment", "compute") fn atomic_fetch_min_explicit[T: iu32, S: workgroup_or_storage](ptr<S, atomic<T>, read_write>, T, u32) -> T
+@stage("fragment", "compute") fn atomic_fetch_or_explicit[T: iu32, S: workgroup_or_storage](ptr<S, atomic<T>, read_write>, T, u32) -> T
+@stage("fragment", "compute") fn atomic_fetch_sub_explicit[T: iu32, S: workgroup_or_storage](ptr<S, atomic<T>, read_write>, T, u32) -> T
+@stage("fragment", "compute") fn atomic_fetch_xor_explicit[T: iu32, S: workgroup_or_storage](ptr<S, atomic<T>, read_write>, T, u32) -> T
+@stage("fragment", "compute") fn atomic_load_explicit[T: iu32, S: workgroup_or_storage](ptr<S, atomic<T>, read_write>, u32) -> T
+@stage("fragment", "compute") fn atomic_store_explicit[T: iu32, S: workgroup_or_storage](ptr<S, atomic<T>, read_write>, T, u32)
 @stage("compute") fn threadgroup_barrier(u32)
 
diff --git a/src/tint/lang/msl/writer/printer/printer.cc b/src/tint/lang/msl/writer/printer/printer.cc
index 996010e..fc15cc6 100644
--- a/src/tint/lang/msl/writer/printer/printer.cc
+++ b/src/tint/lang/msl/writer/printer/printer.cc
@@ -27,6 +27,8 @@
 
 #include "src/tint/lang/msl/writer/printer/printer.h"
 
+#include <atomic>
+#include <cstdint>
 #include <unordered_map>
 #include <unordered_set>
 #include <utility>
@@ -85,7 +87,9 @@
 #include "src/tint/lang/core/type/vector.h"
 #include "src/tint/lang/core/type/void.h"
 #include "src/tint/lang/msl/barrier_type.h"
+#include "src/tint/lang/msl/builtin_fn.h"
 #include "src/tint/lang/msl/ir/builtin_call.h"
+#include "src/tint/lang/msl/ir/memory_order.h"
 #include "src/tint/lang/msl/writer/common/printer_support.h"
 #include "src/tint/utils/containers/map.h"
 #include "src/tint/utils/generator/text_generator.h"
@@ -814,33 +818,40 @@
     }
 
     void EmitMslBuiltinCall(StringStream& out, const msl::ir::BuiltinCall* c) {
-        switch (c->Func()) {
-            case msl::BuiltinFn::kThreadgroupBarrier: {
-                auto flags = c->Args()[0]->As<core::ir::Constant>()->Value()->ValueAs<uint8_t>();
-                out << "threadgroup_barrier(";
-                bool emitted_flag = false;
+        if (c->Func() == msl::BuiltinFn::kThreadgroupBarrier) {
+            auto flags = c->Args()[0]->As<core::ir::Constant>()->Value()->ValueAs<uint8_t>();
+            out << "threadgroup_barrier(";
+            bool emitted_flag = false;
 
-                auto emit = [&](BarrierType type, const std::string& name) {
-                    if ((flags & type) != type) {
-                        return;
-                    }
+            auto emit = [&](BarrierType type, const std::string& name) {
+                if ((flags & type) != type) {
+                    return;
+                }
 
-                    if (emitted_flag) {
-                        out << " | ";
-                    }
-                    emitted_flag = true;
-                    out << "mem_flags::mem_" << name;
-                };
-                emit(BarrierType::kDevice, "device");
-                emit(BarrierType::kThreadGroup, "threadgroup");
-                emit(BarrierType::kTexture, "texture");
+                if (emitted_flag) {
+                    out << " | ";
+                }
+                emitted_flag = true;
+                out << "mem_flags::mem_" << name;
+            };
+            emit(BarrierType::kDevice, "device");
+            emit(BarrierType::kThreadGroup, "threadgroup");
+            emit(BarrierType::kTexture, "texture");
 
-                out << ")";
-                return;
-            }
-            default:
-                TINT_ICE() << "undefined MSL ir function";
+            out << ")";
+            return;
         }
+
+        out << c->Func() << "(";
+        bool needs_comma = false;
+        for (const auto* arg : c->Args()) {
+            if (needs_comma) {
+                out << ", ";
+            }
+            EmitAndTakeAddressIfNeeded(out, arg);
+            needs_comma = true;
+        }
+        out << ")";
     }
 
     void EmitCoreBuiltinCall(StringStream& out, const core::ir::CoreBuiltinCall* c) {
@@ -1368,6 +1379,14 @@
     /// @param out the stream to write the constant too
     /// @param c the constant to emit
     void EmitConstant(StringStream& out, const core::ir::Constant* c) {
+        // Special case for memory_order enum values.
+        if (auto* order = c->As<msl::ir::MemoryOrder>()) {
+            TINT_ASSERT(order->Value()->ValueAs<u32>() ==
+                        static_cast<u32>(std::memory_order_relaxed));
+            out << "memory_order_relaxed";
+            return;
+        }
+
         EmitConstant(out, c->Value());
     }
 
diff --git a/src/tint/lang/msl/writer/raise/builtin_polyfill.cc b/src/tint/lang/msl/writer/raise/builtin_polyfill.cc
index e44d1a6..cde7682 100644
--- a/src/tint/lang/msl/writer/raise/builtin_polyfill.cc
+++ b/src/tint/lang/msl/writer/raise/builtin_polyfill.cc
@@ -27,6 +27,7 @@
 
 #include "src/tint/lang/msl/writer/raise/builtin_polyfill.h"
 
+#include <atomic>
 #include <utility>
 
 #include "src/tint/lang/core/fluent_types.h"
@@ -35,7 +36,9 @@
 #include "src/tint/lang/core/ir/core_builtin_call.h"
 #include "src/tint/lang/core/ir/validator.h"
 #include "src/tint/lang/msl/barrier_type.h"
+#include "src/tint/lang/msl/builtin_fn.h"
 #include "src/tint/lang/msl/ir/builtin_call.h"
+#include "src/tint/lang/msl/ir/memory_order.h"
 
 namespace tint::msl::writer::raise {
 namespace {
@@ -60,6 +63,16 @@
         for (auto* inst : ir.Instructions()) {
             if (auto* builtin = inst->As<core::ir::CoreBuiltinCall>()) {
                 switch (builtin->Func()) {
+                    case core::BuiltinFn::kAtomicAdd:
+                    case core::BuiltinFn::kAtomicAnd:
+                    case core::BuiltinFn::kAtomicExchange:
+                    case core::BuiltinFn::kAtomicLoad:
+                    case core::BuiltinFn::kAtomicMax:
+                    case core::BuiltinFn::kAtomicMin:
+                    case core::BuiltinFn::kAtomicOr:
+                    case core::BuiltinFn::kAtomicStore:
+                    case core::BuiltinFn::kAtomicSub:
+                    case core::BuiltinFn::kAtomicXor:
                     case core::BuiltinFn::kStorageBarrier:
                     case core::BuiltinFn::kWorkgroupBarrier:
                     case core::BuiltinFn::kTextureBarrier:
@@ -74,6 +87,36 @@
         // Replace the builtins that we found.
         for (auto* builtin : worklist) {
             switch (builtin->Func()) {
+                case core::BuiltinFn::kAtomicAdd:
+                    AtomicCall(builtin, msl::BuiltinFn::kAtomicFetchAddExplicit);
+                    break;
+                case core::BuiltinFn::kAtomicAnd:
+                    AtomicCall(builtin, msl::BuiltinFn::kAtomicFetchAndExplicit);
+                    break;
+                case core::BuiltinFn::kAtomicExchange:
+                    AtomicCall(builtin, msl::BuiltinFn::kAtomicExchangeExplicit);
+                    break;
+                case core::BuiltinFn::kAtomicLoad:
+                    AtomicCall(builtin, msl::BuiltinFn::kAtomicLoadExplicit);
+                    break;
+                case core::BuiltinFn::kAtomicMax:
+                    AtomicCall(builtin, msl::BuiltinFn::kAtomicFetchMaxExplicit);
+                    break;
+                case core::BuiltinFn::kAtomicMin:
+                    AtomicCall(builtin, msl::BuiltinFn::kAtomicFetchMinExplicit);
+                    break;
+                case core::BuiltinFn::kAtomicOr:
+                    AtomicCall(builtin, msl::BuiltinFn::kAtomicFetchOrExplicit);
+                    break;
+                case core::BuiltinFn::kAtomicStore:
+                    AtomicCall(builtin, msl::BuiltinFn::kAtomicStoreExplicit);
+                    break;
+                case core::BuiltinFn::kAtomicSub:
+                    AtomicCall(builtin, msl::BuiltinFn::kAtomicFetchSubExplicit);
+                    break;
+                case core::BuiltinFn::kAtomicXor:
+                    AtomicCall(builtin, msl::BuiltinFn::kAtomicFetchXorExplicit);
+                    break;
                 case core::BuiltinFn::kStorageBarrier:
                     ThreadgroupBarrier(builtin, BarrierType::kDevice);
                     break;
@@ -89,6 +132,18 @@
         }
     }
 
+    /// Replace an atomic builtin call with an equivalent MSL intrinsic.
+    /// @param builtin the builtin call instruction
+    void AtomicCall(core::ir::CoreBuiltinCall* builtin, msl::BuiltinFn intrinsic) {
+        auto args = Vector<core::ir::Value*, 4>{builtin->Args()};
+        args.Push(ir.allocators.values.Create<msl::ir::MemoryOrder>(
+            b.ConstantValue(u32(std::memory_order_relaxed))));
+        auto* call = b.CallWithResult<msl::ir::BuiltinCall>(builtin->DetachResult(), intrinsic,
+                                                            std::move(args));
+        call->InsertBefore(builtin);
+        builtin->Destroy();
+    }
+
     /// Replace a barrier builtin with the `threadgroupBarrier()` intrinsic.
     /// @param builtin the builtin call instruction
     /// @param type the barrier type
diff --git a/src/tint/lang/msl/writer/raise/builtin_polyfill_test.cc b/src/tint/lang/msl/writer/raise/builtin_polyfill_test.cc
index bf8a720..a476af1 100644
--- a/src/tint/lang/msl/writer/raise/builtin_polyfill_test.cc
+++ b/src/tint/lang/msl/writer/raise/builtin_polyfill_test.cc
@@ -29,20 +29,384 @@
 
 #include <utility>
 
+#include "gtest/gtest.h"
+#include "src/tint/lang/core/fluent_types.h"
 #include "src/tint/lang/core/ir/transform/helper_test.h"
-#include "src/tint/lang/core/type/array.h"
+#include "src/tint/lang/core/number.h"
 #include "src/tint/lang/core/type/atomic.h"
 #include "src/tint/lang/core/type/builtin_structs.h"
-#include "src/tint/lang/core/type/depth_texture.h"
-#include "src/tint/lang/core/type/multisampled_texture.h"
-#include "src/tint/lang/core/type/sampled_texture.h"
-#include "src/tint/lang/core/type/storage_texture.h"
+
+using namespace tint::core::fluent_types;     // NOLINT
+using namespace tint::core::number_suffixes;  // NOLINT
 
 namespace tint::msl::writer::raise {
 namespace {
 
 using MslWriter_BuiltinPolyfillTest = core::ir::transform::TransformTest;
 
+TEST_F(MslWriter_BuiltinPolyfillTest, AtomicAdd_Workgroup_I32) {
+    auto* a = b.FunctionParam<ptr<workgroup, atomic<i32>>>("a");
+    auto* func = b.Function("foo", ty.i32());
+    func->SetParams({a});
+    b.Append(func->Block(), [&] {
+        auto* result = b.Call<i32>(core::BuiltinFn::kAtomicAdd, a, 1_i);
+        b.Return(func, result);
+    });
+
+    auto* src = R"(
+%foo = func(%a:ptr<workgroup, atomic<i32>, read_write>):i32 {
+  $B1: {
+    %3:i32 = atomicAdd %a, 1i
+    ret %3
+  }
+}
+)";
+    EXPECT_EQ(src, str());
+
+    auto* expect = R"(
+%foo = func(%a:ptr<workgroup, atomic<i32>, read_write>):i32 {
+  $B1: {
+    %3:i32 = msl.atomic_fetch_add_explicit %a, 1i, 0u
+    ret %3
+  }
+}
+)";
+
+    Run(BuiltinPolyfill);
+
+    EXPECT_EQ(expect, str());
+}
+
+TEST_F(MslWriter_BuiltinPolyfillTest, AtomicAdd_Storage_U32) {
+    auto* a = b.FunctionParam<ptr<storage, atomic<u32>>>("a");
+    auto* func = b.Function("foo", ty.u32());
+    func->SetParams({a});
+    b.Append(func->Block(), [&] {
+        auto* result = b.Call<u32>(core::BuiltinFn::kAtomicAdd, a, 1_u);
+        b.Return(func, result);
+    });
+
+    auto* src = R"(
+%foo = func(%a:ptr<storage, atomic<u32>, read_write>):u32 {
+  $B1: {
+    %3:u32 = atomicAdd %a, 1u
+    ret %3
+  }
+}
+)";
+    EXPECT_EQ(src, str());
+
+    auto* expect = R"(
+%foo = func(%a:ptr<storage, atomic<u32>, read_write>):u32 {
+  $B1: {
+    %3:u32 = msl.atomic_fetch_add_explicit %a, 1u, 0u
+    ret %3
+  }
+}
+)";
+
+    Run(BuiltinPolyfill);
+
+    EXPECT_EQ(expect, str());
+}
+
+TEST_F(MslWriter_BuiltinPolyfillTest, AtomicAnd) {
+    auto* a = b.FunctionParam<ptr<workgroup, atomic<i32>>>("a");
+    auto* func = b.Function("foo", ty.i32());
+    func->SetParams({a});
+    b.Append(func->Block(), [&] {
+        auto* result = b.Call<i32>(core::BuiltinFn::kAtomicAnd, a, 1_i);
+        b.Return(func, result);
+    });
+
+    auto* src = R"(
+%foo = func(%a:ptr<workgroup, atomic<i32>, read_write>):i32 {
+  $B1: {
+    %3:i32 = atomicAnd %a, 1i
+    ret %3
+  }
+}
+)";
+    EXPECT_EQ(src, str());
+
+    auto* expect = R"(
+%foo = func(%a:ptr<workgroup, atomic<i32>, read_write>):i32 {
+  $B1: {
+    %3:i32 = msl.atomic_fetch_and_explicit %a, 1i, 0u
+    ret %3
+  }
+}
+)";
+
+    Run(BuiltinPolyfill);
+
+    EXPECT_EQ(expect, str());
+}
+
+TEST_F(MslWriter_BuiltinPolyfillTest, AtomicExchange) {
+    auto* a = b.FunctionParam<ptr<workgroup, atomic<i32>>>("a");
+    auto* func = b.Function("foo", ty.i32());
+    func->SetParams({a});
+    b.Append(func->Block(), [&] {
+        auto* result = b.Call<i32>(core::BuiltinFn::kAtomicExchange, a, 1_i);
+        b.Return(func, result);
+    });
+
+    auto* src = R"(
+%foo = func(%a:ptr<workgroup, atomic<i32>, read_write>):i32 {
+  $B1: {
+    %3:i32 = atomicExchange %a, 1i
+    ret %3
+  }
+}
+)";
+    EXPECT_EQ(src, str());
+
+    auto* expect = R"(
+%foo = func(%a:ptr<workgroup, atomic<i32>, read_write>):i32 {
+  $B1: {
+    %3:i32 = msl.atomic_exchange_explicit %a, 1i, 0u
+    ret %3
+  }
+}
+)";
+
+    Run(BuiltinPolyfill);
+
+    EXPECT_EQ(expect, str());
+}
+
+TEST_F(MslWriter_BuiltinPolyfillTest, AtomicLoad) {
+    auto* a = b.FunctionParam<ptr<workgroup, atomic<i32>>>("a");
+    auto* func = b.Function("foo", ty.i32());
+    func->SetParams({a});
+    b.Append(func->Block(), [&] {
+        auto* result = b.Call<i32>(core::BuiltinFn::kAtomicLoad, a);
+        b.Return(func, result);
+    });
+
+    auto* src = R"(
+%foo = func(%a:ptr<workgroup, atomic<i32>, read_write>):i32 {
+  $B1: {
+    %3:i32 = atomicLoad %a
+    ret %3
+  }
+}
+)";
+    EXPECT_EQ(src, str());
+
+    auto* expect = R"(
+%foo = func(%a:ptr<workgroup, atomic<i32>, read_write>):i32 {
+  $B1: {
+    %3:i32 = msl.atomic_load_explicit %a, 0u
+    ret %3
+  }
+}
+)";
+
+    Run(BuiltinPolyfill);
+
+    EXPECT_EQ(expect, str());
+}
+
+TEST_F(MslWriter_BuiltinPolyfillTest, AtomicMax) {
+    auto* a = b.FunctionParam<ptr<workgroup, atomic<i32>>>("a");
+    auto* func = b.Function("foo", ty.i32());
+    func->SetParams({a});
+    b.Append(func->Block(), [&] {
+        auto* result = b.Call<i32>(core::BuiltinFn::kAtomicMax, a, 1_i);
+        b.Return(func, result);
+    });
+
+    auto* src = R"(
+%foo = func(%a:ptr<workgroup, atomic<i32>, read_write>):i32 {
+  $B1: {
+    %3:i32 = atomicMax %a, 1i
+    ret %3
+  }
+}
+)";
+    EXPECT_EQ(src, str());
+
+    auto* expect = R"(
+%foo = func(%a:ptr<workgroup, atomic<i32>, read_write>):i32 {
+  $B1: {
+    %3:i32 = msl.atomic_fetch_max_explicit %a, 1i, 0u
+    ret %3
+  }
+}
+)";
+
+    Run(BuiltinPolyfill);
+
+    EXPECT_EQ(expect, str());
+}
+
+TEST_F(MslWriter_BuiltinPolyfillTest, AtomicMin) {
+    auto* a = b.FunctionParam<ptr<workgroup, atomic<i32>>>("a");
+    auto* func = b.Function("foo", ty.i32());
+    func->SetParams({a});
+    b.Append(func->Block(), [&] {
+        auto* result = b.Call<i32>(core::BuiltinFn::kAtomicMin, a, 1_i);
+        b.Return(func, result);
+    });
+
+    auto* src = R"(
+%foo = func(%a:ptr<workgroup, atomic<i32>, read_write>):i32 {
+  $B1: {
+    %3:i32 = atomicMin %a, 1i
+    ret %3
+  }
+}
+)";
+    EXPECT_EQ(src, str());
+
+    auto* expect = R"(
+%foo = func(%a:ptr<workgroup, atomic<i32>, read_write>):i32 {
+  $B1: {
+    %3:i32 = msl.atomic_fetch_min_explicit %a, 1i, 0u
+    ret %3
+  }
+}
+)";
+
+    Run(BuiltinPolyfill);
+
+    EXPECT_EQ(expect, str());
+}
+
+TEST_F(MslWriter_BuiltinPolyfillTest, AtomicOr) {
+    auto* a = b.FunctionParam<ptr<workgroup, atomic<i32>>>("a");
+    auto* func = b.Function("foo", ty.i32());
+    func->SetParams({a});
+    b.Append(func->Block(), [&] {
+        auto* result = b.Call<i32>(core::BuiltinFn::kAtomicOr, a, 1_i);
+        b.Return(func, result);
+    });
+
+    auto* src = R"(
+%foo = func(%a:ptr<workgroup, atomic<i32>, read_write>):i32 {
+  $B1: {
+    %3:i32 = atomicOr %a, 1i
+    ret %3
+  }
+}
+)";
+    EXPECT_EQ(src, str());
+
+    auto* expect = R"(
+%foo = func(%a:ptr<workgroup, atomic<i32>, read_write>):i32 {
+  $B1: {
+    %3:i32 = msl.atomic_fetch_or_explicit %a, 1i, 0u
+    ret %3
+  }
+}
+)";
+
+    Run(BuiltinPolyfill);
+
+    EXPECT_EQ(expect, str());
+}
+
+TEST_F(MslWriter_BuiltinPolyfillTest, AtomicStore) {
+    auto* a = b.FunctionParam<ptr<workgroup, atomic<i32>>>("a");
+    auto* func = b.Function("foo", ty.void_());
+    func->SetParams({a});
+    b.Append(func->Block(), [&] {
+        b.Call<void>(core::BuiltinFn::kAtomicStore, a, 1_i);
+        b.Return(func);
+    });
+
+    auto* src = R"(
+%foo = func(%a:ptr<workgroup, atomic<i32>, read_write>):void {
+  $B1: {
+    %3:void = atomicStore %a, 1i
+    ret
+  }
+}
+)";
+    EXPECT_EQ(src, str());
+
+    auto* expect = R"(
+%foo = func(%a:ptr<workgroup, atomic<i32>, read_write>):void {
+  $B1: {
+    %3:void = msl.atomic_store_explicit %a, 1i, 0u
+    ret
+  }
+}
+)";
+
+    Run(BuiltinPolyfill);
+
+    EXPECT_EQ(expect, str());
+}
+
+TEST_F(MslWriter_BuiltinPolyfillTest, AtomicSub) {
+    auto* a = b.FunctionParam<ptr<workgroup, atomic<i32>>>("a");
+    auto* func = b.Function("foo", ty.i32());
+    func->SetParams({a});
+    b.Append(func->Block(), [&] {
+        auto* result = b.Call<i32>(core::BuiltinFn::kAtomicSub, a, 1_i);
+        b.Return(func, result);
+    });
+
+    auto* src = R"(
+%foo = func(%a:ptr<workgroup, atomic<i32>, read_write>):i32 {
+  $B1: {
+    %3:i32 = atomicSub %a, 1i
+    ret %3
+  }
+}
+)";
+    EXPECT_EQ(src, str());
+
+    auto* expect = R"(
+%foo = func(%a:ptr<workgroup, atomic<i32>, read_write>):i32 {
+  $B1: {
+    %3:i32 = msl.atomic_fetch_sub_explicit %a, 1i, 0u
+    ret %3
+  }
+}
+)";
+
+    Run(BuiltinPolyfill);
+
+    EXPECT_EQ(expect, str());
+}
+
+TEST_F(MslWriter_BuiltinPolyfillTest, AtomicXor) {
+    auto* a = b.FunctionParam<ptr<workgroup, atomic<i32>>>("a");
+    auto* func = b.Function("foo", ty.i32());
+    func->SetParams({a});
+    b.Append(func->Block(), [&] {
+        auto* result = b.Call<i32>(core::BuiltinFn::kAtomicXor, a, 1_i);
+        b.Return(func, result);
+    });
+
+    auto* src = R"(
+%foo = func(%a:ptr<workgroup, atomic<i32>, read_write>):i32 {
+  $B1: {
+    %3:i32 = atomicXor %a, 1i
+    ret %3
+  }
+}
+)";
+    EXPECT_EQ(src, str());
+
+    auto* expect = R"(
+%foo = func(%a:ptr<workgroup, atomic<i32>, read_write>):i32 {
+  $B1: {
+    %3:i32 = msl.atomic_fetch_xor_explicit %a, 1i, 0u
+    ret %3
+  }
+}
+)";
+
+    Run(BuiltinPolyfill);
+
+    EXPECT_EQ(expect, str());
+}
+
 TEST_F(MslWriter_BuiltinPolyfillTest, WorkgroupBarrier) {
     auto* func = b.Function("foo", ty.void_());
     func->SetStage(core::ir::Function::PipelineStage::kCompute);
diff --git a/test/tint/access/ptr.wgsl.expected.ir.msl b/test/tint/access/ptr.wgsl.expected.ir.msl
index 0c53820..43ad3e6 100644
--- a/test/tint/access/ptr.wgsl.expected.ir.msl
+++ b/test/tint/access/ptr.wgsl.expected.ir.msl
@@ -1,128 +1,64 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct S {
+  int a;
+  int b;
+};
+struct tint_module_vars_struct {
+  device int* s;
+  threadgroup atomic_int* g1;
+};
+struct tint_symbol_2 {
+  atomic_int tint_symbol_1;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: S = struct @align(4) {
-  a:i32 @offset(0)
-  b:i32 @offset(4)
+int accept_value(int val) {
+  return val;
 }
-
-$B1: {  # root
-  %s:ptr<storage, i32, read_write> = var @binding_point(0, 0)
-  %g1:ptr<workgroup, atomic<i32>, read_write> = var
+int accept_ptr_deref_call_func(thread int* const val) {
+  int const v = (*val);
+  return (v + accept_value((*val)));
 }
-
-%accept_value = func(%val:i32):i32 {
-  $B2: {
-    ret %val
+int accept_ptr_deref_pass_through(thread int* const val) {
+  int const v_1 = (*val);
+  return (v_1 + accept_ptr_deref_call_func(val));
+}
+int accept_ptr_to_struct_and_access(thread S* const val) {
+  return ((*val).a + (*val).b);
+}
+int accept_ptr_to_struct_access_pass_ptr(thread S* const val) {
+  thread int* const b = (&(*val).a);
+  (*b) = 2;
+  return (*b);
+}
+int tint_f32_to_i32(float value) {
+  return select(2147483647, select((-2147483647 - 1), int(value), (value >= -2147483648.0f)), (value <= 2147483520.0f));
+}
+int accept_ptr_vec_access_elements(thread float3* const v1) {
+  (*v1)[0u] = cross((*v1), (*v1))[0u];
+  return tint_f32_to_i32((*v1)[0u]);
+}
+int call_builtin_with_mod_scope_ptr(tint_module_vars_struct tint_module_vars) {
+  return atomic_load_explicit(tint_module_vars.g1, memory_order_relaxed);
+}
+void tint_symbol_inner(uint tint_local_index, tint_module_vars_struct tint_module_vars) {
+  if ((tint_local_index == 0u)) {
+    atomic_store_explicit(tint_module_vars.g1, 0, memory_order_relaxed);
   }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  int v1 = 0;
+  S v2 = S{};
+  thread S* const v3 = (&v2);
+  float3 v4 = float3(0.0f);
+  int const t1 = atomic_load_explicit(tint_module_vars.g1, memory_order_relaxed);
+  int const v_2 = accept_ptr_deref_pass_through((&v1));
+  int const v_3 = (v_2 + accept_ptr_to_struct_and_access((&v2)));
+  int const v_4 = (v_3 + accept_ptr_to_struct_and_access(v3));
+  int const v_5 = (v_4 + accept_ptr_vec_access_elements((&v4)));
+  int const v_6 = (v_5 + accept_ptr_to_struct_access_pass_ptr((&v2)));
+  (*tint_module_vars.s) = ((v_6 + call_builtin_with_mod_scope_ptr(tint_module_vars)) + t1);
 }
-%accept_ptr_deref_call_func = func(%val_1:ptr<function, i32, read_write>):i32 {  # %val_1: 'val'
-  $B3: {
-    %7:i32 = load %val_1
-    %8:i32 = let %7
-    %9:i32 = load %val_1
-    %10:i32 = call %accept_value, %9
-    %11:i32 = add %8, %10
-    ret %11
-  }
+kernel void tint_symbol(uint tint_local_index [[thread_index_in_threadgroup]], device int* s [[buffer(0)]], threadgroup tint_symbol_2* v_7 [[threadgroup(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.s=s, .g1=(&(*v_7).tint_symbol_1)};
+  tint_symbol_inner(tint_local_index, tint_module_vars);
 }
-%accept_ptr_deref_pass_through = func(%val_2:ptr<function, i32, read_write>):i32 {  # %val_2: 'val'
-  $B4: {
-    %14:i32 = load %val_2
-    %15:i32 = let %14
-    %16:i32 = call %accept_ptr_deref_call_func, %val_2
-    %17:i32 = add %15, %16
-    ret %17
-  }
-}
-%accept_ptr_to_struct_and_access = func(%val_3:ptr<function, S, read_write>):i32 {  # %val_3: 'val'
-  $B5: {
-    %20:ptr<function, i32, read_write> = access %val_3, 0u
-    %21:i32 = load %20
-    %22:ptr<function, i32, read_write> = access %val_3, 1u
-    %23:i32 = load %22
-    %24:i32 = add %21, %23
-    ret %24
-  }
-}
-%accept_ptr_to_struct_access_pass_ptr = func(%val_4:ptr<function, S, read_write>):i32 {  # %val_4: 'val'
-  $B6: {
-    %27:ptr<function, i32, read_write> = access %val_4, 0u
-    %b:ptr<function, i32, read_write> = let %27
-    store %b, 2i
-    %29:i32 = load %b
-    ret %29
-  }
-}
-%accept_ptr_vec_access_elements = func(%v1:ptr<function, vec3<f32>, read_write>):i32 {
-  $B7: {
-    %32:vec3<f32> = load %v1
-    %33:vec3<f32> = load %v1
-    %34:vec3<f32> = cross %32, %33
-    %35:f32 = access %34, 0u
-    store_vector_element %v1, 0u, %35
-    %36:f32 = load_vector_element %v1, 0u
-    %37:i32 = call %tint_f32_to_i32, %36
-    ret %37
-  }
-}
-%call_builtin_with_mod_scope_ptr = func():i32 {
-  $B8: {
-    %40:i32 = atomicLoad %g1
-    ret %40
-  }
-}
-%tint_symbol = @compute @workgroup_size(1, 1, 1) func(%tint_local_index:u32 [@local_invocation_index]):void {
-  $B9: {
-    %43:bool = eq %tint_local_index, 0u
-    if %43 [t: $B10] {  # if_1
-      $B10: {  # true
-        %44:void = atomicStore %g1, 0i
-        exit_if  # if_1
-      }
-    }
-    %45:void = msl.threadgroup_barrier 4u
-    %v1_1:ptr<function, i32, read_write> = var, 0i  # %v1_1: 'v1'
-    %v2:ptr<function, S, read_write> = var, S(0i)
-    %v3:ptr<function, S, read_write> = let %v2
-    %v4:ptr<function, vec3<f32>, read_write> = var, vec3<f32>(0.0f)
-    %50:i32 = atomicLoad %g1
-    %t1:i32 = let %50
-    %52:i32 = call %accept_ptr_deref_pass_through, %v1_1
-    %53:i32 = let %52
-    %54:i32 = call %accept_ptr_to_struct_and_access, %v2
-    %55:i32 = add %53, %54
-    %56:i32 = let %55
-    %57:i32 = call %accept_ptr_to_struct_and_access, %v3
-    %58:i32 = add %56, %57
-    %59:i32 = let %58
-    %60:i32 = call %accept_ptr_vec_access_elements, %v4
-    %61:i32 = add %59, %60
-    %62:i32 = let %61
-    %63:i32 = call %accept_ptr_to_struct_access_pass_ptr, %v2
-    %64:i32 = add %62, %63
-    %65:i32 = let %64
-    %66:i32 = call %call_builtin_with_mod_scope_ptr
-    %67:i32 = add %65, %66
-    %68:i32 = add %67, %t1
-    store %s, %68
-    ret
-  }
-}
-%tint_f32_to_i32 = func(%value:f32):i32 {
-  $B11: {
-    %70:i32 = convert %value
-    %71:bool = gte %value, -2147483648.0f
-    %72:i32 = select -2147483648i, %70, %71
-    %73:bool = lte %value, 2147483520.0f
-    %74:i32 = select 2147483647i, %72, %73
-    ret %74
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/benchmark/cluster-lights.wgsl.expected.ir.msl b/test/tint/benchmark/cluster-lights.wgsl.expected.ir.msl
deleted file mode 100644
index 541e21a..0000000
--- a/test/tint/benchmark/cluster-lights.wgsl.expected.ir.msl
+++ /dev/null
@@ -1,376 +0,0 @@
-SKIP: FAILED
-
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: Camera = struct @align(16) {
-  projection:mat4x4<f32> @offset(0)
-  inverseProjection:mat4x4<f32> @offset(64)
-  view:mat4x4<f32> @offset(128)
-  position:vec3<f32> @offset(192)
-  time:f32 @offset(204)
-  outputSize:vec2<f32> @offset(208)
-  zNear:f32 @offset(216)
-  zFar:f32 @offset(220)
-}
-
-ClusterBounds = struct @align(16) {
-  minAABB:vec3<f32> @offset(0)
-  maxAABB:vec3<f32> @offset(16)
-}
-
-Clusters = struct @align(16) {
-  bounds:array<ClusterBounds, 27648> @offset(0)
-}
-
-ClusterLights = struct @align(4) {
-  offset:u32 @offset(0)
-  count:u32 @offset(4)
-}
-
-ClusterLightGroup = struct @align(4) {
-  offset:atomic<u32> @offset(0)
-  lights:array<ClusterLights, 27648> @offset(4)
-  indices:array<u32, 1769472> @offset(221188)
-}
-
-Light = struct @align(16) {
-  position:vec3<f32> @offset(0)
-  range:f32 @offset(12)
-  color:vec3<f32> @offset(16)
-  intensity:f32 @offset(28)
-}
-
-GlobalLights = struct @align(16) {
-  ambient:vec3<f32> @offset(0)
-  dirColor:vec3<f32> @offset(16)
-  dirIntensity:f32 @offset(28)
-  dirDirection:vec3<f32> @offset(32)
-  lightCount:u32 @offset(44)
-  lights:array<Light> @offset(48)
-}
-
-$B1: {  # root
-  %camera:ptr<uniform, Camera, read> = var @binding_point(0, 0)
-  %clusters:ptr<storage, Clusters, read> = var @binding_point(0, 1)
-  %clusterLights:ptr<storage, ClusterLightGroup, read_write> = var @binding_point(0, 2)
-  %globalLights:ptr<storage, GlobalLights, read> = var @binding_point(0, 3)
-}
-
-%linearDepth = func(%depthSample:f32):f32 {
-  $B2: {
-    %7:ptr<uniform, f32, read> = access %camera, 7u
-    %8:f32 = load %7
-    %9:ptr<uniform, f32, read> = access %camera, 6u
-    %10:f32 = load %9
-    %11:f32 = mul %8, %10
-    %12:f32 = let %11
-    %13:ptr<uniform, f32, read> = access %camera, 6u
-    %14:f32 = load %13
-    %15:ptr<uniform, f32, read> = access %camera, 7u
-    %16:f32 = load %15
-    %17:f32 = sub %14, %16
-    %18:ptr<uniform, f32, read> = access %camera, 7u
-    %19:f32 = load %18
-    %20:f32 = fma %depthSample, %17, %19
-    %21:f32 = div %12, %20
-    ret %21
-  }
-}
-%getTile = func(%fragCoord:vec4<f32>):vec3<u32> {
-  $B3: {
-    %24:ptr<uniform, f32, read> = access %camera, 7u
-    %25:f32 = load %24
-    %26:ptr<uniform, f32, read> = access %camera, 6u
-    %27:f32 = load %26
-    %28:f32 = div %25, %27
-    %29:f32 = log2 %28
-    %30:f32 = div 48.0f, %29
-    %sliceScale:f32 = let %30
-    %32:ptr<uniform, f32, read> = access %camera, 6u
-    %33:f32 = load %32
-    %34:f32 = log2 %33
-    %35:f32 = mul 48.0f, %34
-    %36:f32 = let %35
-    %37:ptr<uniform, f32, read> = access %camera, 7u
-    %38:f32 = load %37
-    %39:ptr<uniform, f32, read> = access %camera, 6u
-    %40:f32 = load %39
-    %41:f32 = div %38, %40
-    %42:f32 = log2 %41
-    %43:f32 = div %36, %42
-    %44:f32 = negation %43
-    %sliceBias:f32 = let %44
-    %46:f32 = access %fragCoord, 2u
-    %47:f32 = call %linearDepth, %46
-    %48:f32 = log2 %47
-    %49:f32 = mul %48, %sliceScale
-    %50:f32 = add %49, %sliceBias
-    %51:f32 = max %50, 0.0f
-    %52:u32 = call %tint_f32_to_u32, %51
-    %zTile:u32 = let %52
-    %55:f32 = access %fragCoord, 0u
-    %56:ptr<uniform, vec2<f32>, read> = access %camera, 5u
-    %57:f32 = load_vector_element %56, 0u
-    %58:f32 = div %57, 32.0f
-    %59:f32 = div %55, %58
-    %60:u32 = call %tint_f32_to_u32, %59
-    %61:u32 = let %60
-    %62:f32 = access %fragCoord, 1u
-    %63:ptr<uniform, vec2<f32>, read> = access %camera, 5u
-    %64:f32 = load_vector_element %63, 1u
-    %65:f32 = div %64, 18.0f
-    %66:f32 = div %62, %65
-    %67:u32 = call %tint_f32_to_u32, %66
-    %68:vec3<u32> = construct %61, %67, %zTile
-    ret %68
-  }
-}
-%getClusterIndex = func(%fragCoord_1:vec4<f32>):u32 {  # %fragCoord_1: 'fragCoord'
-  $B4: {
-    %71:vec3<u32> = call %getTile, %fragCoord_1
-    %tile:vec3<u32> = let %71
-    %73:u32 = access %tile, 0u
-    %74:u32 = access %tile, 1u
-    %75:u32 = mul %74, 32u
-    %76:u32 = add %73, %75
-    %77:u32 = access %tile, 2u
-    %78:u32 = mul %77, 32u
-    %79:u32 = mul %78, 18u
-    %80:u32 = add %76, %79
-    ret %80
-  }
-}
-%sqDistPointAABB = func(%p:vec3<f32>, %minAABB:vec3<f32>, %maxAABB:vec3<f32>):f32 {
-  $B5: {
-    %sqDist:ptr<function, f32, read_write> = var, 0.0f
-    loop [i: $B6, b: $B7, c: $B8] {  # loop_1
-      $B6: {  # initializer
-        %i:ptr<function, i32, read_write> = var, 0i
-        next_iteration  # -> $B7
-      }
-      $B7: {  # body
-        %87:i32 = load %i
-        %88:bool = lt %87, 3i
-        if %88 [t: $B9, f: $B10] {  # if_1
-          $B9: {  # true
-            exit_if  # if_1
-          }
-          $B10: {  # false
-            exit_loop  # loop_1
-          }
-        }
-        %89:i32 = load %i
-        %90:f32 = access %p, %89
-        %v:f32 = let %90
-        %92:i32 = load %i
-        %93:f32 = access %minAABB, %92
-        %94:bool = lt %v, %93
-        if %94 [t: $B11] {  # if_2
-          $B11: {  # true
-            %95:f32 = load %sqDist
-            %96:i32 = load %i
-            %97:f32 = access %minAABB, %96
-            %98:f32 = sub %97, %v
-            %99:i32 = load %i
-            %100:f32 = access %minAABB, %99
-            %101:f32 = sub %100, %v
-            %102:f32 = mul %98, %101
-            %103:f32 = add %95, %102
-            store %sqDist, %103
-            exit_if  # if_2
-          }
-        }
-        %104:i32 = load %i
-        %105:f32 = access %maxAABB, %104
-        %106:bool = gt %v, %105
-        if %106 [t: $B12] {  # if_3
-          $B12: {  # true
-            %107:f32 = load %sqDist
-            %108:i32 = load %i
-            %109:f32 = access %maxAABB, %108
-            %110:f32 = sub %v, %109
-            %111:i32 = load %i
-            %112:f32 = access %maxAABB, %111
-            %113:f32 = sub %v, %112
-            %114:f32 = mul %110, %113
-            %115:f32 = add %107, %114
-            store %sqDist, %115
-            exit_if  # if_3
-          }
-        }
-        continue  # -> $B8
-      }
-      $B8: {  # continuing
-        %116:i32 = load %i
-        %117:i32 = add %116, 1i
-        store %i, %117
-        next_iteration  # -> $B7
-      }
-    }
-    %118:f32 = load %sqDist
-    ret %118
-  }
-}
-%computeMain = @compute @workgroup_size(4, 2, 4) func(%global_id:vec3<u32> [@global_invocation_id]):void {
-  $B13: {
-    %121:u32 = access %global_id, 0u
-    %122:u32 = access %global_id, 1u
-    %123:u32 = mul %122, 32u
-    %124:u32 = add %121, %123
-    %125:u32 = access %global_id, 2u
-    %126:u32 = mul %125, 32u
-    %127:u32 = mul %126, 18u
-    %128:u32 = add %124, %127
-    %tileIndex:u32 = let %128
-    %clusterLightCount:ptr<function, u32, read_write> = var, 0u
-    %cluserLightIndices:ptr<function, array<u32, 256>, read_write> = var
-    loop [i: $B14, b: $B15, c: $B16] {  # loop_2
-      $B14: {  # initializer
-        %i_1:ptr<function, u32, read_write> = var, 0u  # %i_1: 'i'
-        next_iteration  # -> $B15
-      }
-      $B15: {  # body
-        %133:u32 = load %i_1
-        %134:ptr<storage, u32, read> = access %globalLights, 4u
-        %135:u32 = load %134
-        %136:bool = lt %133, %135
-        if %136 [t: $B17, f: $B18] {  # if_4
-          $B17: {  # true
-            exit_if  # if_4
-          }
-          $B18: {  # false
-            exit_loop  # loop_2
-          }
-        }
-        %137:u32 = load %i_1
-        %138:ptr<storage, f32, read> = access %globalLights, 5u, %137, 1u
-        %139:f32 = load %138
-        %range:f32 = let %139
-        %141:bool = lte %range, 0.0f
-        %lightInCluster:ptr<function, bool, read_write> = var, %141
-        %143:bool = load %lightInCluster
-        %144:bool = eq %143, false
-        if %144 [t: $B19] {  # if_5
-          $B19: {  # true
-            %145:ptr<uniform, mat4x4<f32>, read> = access %camera, 2u
-            %146:mat4x4<f32> = load %145
-            %147:mat4x4<f32> = let %146
-            %148:u32 = load %i_1
-            %149:ptr<storage, vec3<f32>, read> = access %globalLights, 5u, %148, 0u
-            %150:vec3<f32> = load %149
-            %151:vec4<f32> = construct %150, 1.0f
-            %152:vec4<f32> = mul %147, %151
-            %lightViewPos:vec4<f32> = let %152
-            %154:vec3<f32> = swizzle %lightViewPos, xyz
-            %155:ptr<storage, vec3<f32>, read> = access %clusters, 0u, %tileIndex, 0u
-            %156:vec3<f32> = load %155
-            %157:ptr<storage, vec3<f32>, read> = access %clusters, 0u, %tileIndex, 1u
-            %158:vec3<f32> = load %157
-            %159:f32 = call %sqDistPointAABB, %154, %156, %158
-            %sqDist_1:f32 = let %159  # %sqDist_1: 'sqDist'
-            %161:f32 = mul %range, %range
-            %162:bool = lte %sqDist_1, %161
-            store %lightInCluster, %162
-            exit_if  # if_5
-          }
-        }
-        %163:bool = load %lightInCluster
-        if %163 [t: $B20] {  # if_6
-          $B20: {  # true
-            %164:u32 = load %clusterLightCount
-            %165:ptr<function, u32, read_write> = access %cluserLightIndices, %164
-            %166:u32 = load %i_1
-            store %165, %166
-            %167:u32 = load %clusterLightCount
-            %168:u32 = add %167, 1u
-            store %clusterLightCount, %168
-            exit_if  # if_6
-          }
-        }
-        %169:u32 = load %clusterLightCount
-        %170:bool = eq %169, 256u
-        if %170 [t: $B21] {  # if_7
-          $B21: {  # true
-            exit_loop  # loop_2
-          }
-        }
-        continue  # -> $B16
-      }
-      $B16: {  # continuing
-        %171:u32 = load %i_1
-        %172:u32 = add %171, 1u
-        store %i_1, %172
-        next_iteration  # -> $B15
-      }
-    }
-    %173:u32 = load %clusterLightCount
-    %lightCount:u32 = let %173
-    %175:ptr<storage, atomic<u32>, read_write> = access %clusterLights, 0u
-    %176:u32 = atomicAdd %175, %lightCount
-    %offset:ptr<function, u32, read_write> = var, %176
-    %178:u32 = load %offset
-    %179:bool = gte %178, 1769472u
-    if %179 [t: $B22] {  # if_8
-      $B22: {  # true
-        ret
-      }
-    }
-    loop [i: $B23, b: $B24, c: $B25] {  # loop_3
-      $B23: {  # initializer
-        %i_2:ptr<function, u32, read_write> = var, 0u  # %i_2: 'i'
-        next_iteration  # -> $B24
-      }
-      $B24: {  # body
-        %181:u32 = load %i_2
-        %182:u32 = load %clusterLightCount
-        %183:bool = lt %181, %182
-        if %183 [t: $B26, f: $B27] {  # if_9
-          $B26: {  # true
-            exit_if  # if_9
-          }
-          $B27: {  # false
-            exit_loop  # loop_3
-          }
-        }
-        %184:u32 = load %offset
-        %185:u32 = load %i_2
-        %186:u32 = add %184, %185
-        %187:ptr<storage, u32, read_write> = access %clusterLights, 2u, %186
-        %188:u32 = load %i_2
-        %189:ptr<function, u32, read_write> = access %cluserLightIndices, %188
-        %190:u32 = load %189
-        store %187, %190
-        continue  # -> $B25
-      }
-      $B25: {  # continuing
-        %191:u32 = load %i_2
-        %192:u32 = add %191, 1u
-        store %i_2, %192
-        next_iteration  # -> $B24
-      }
-    }
-    %193:ptr<storage, u32, read_write> = access %clusterLights, 1u, %tileIndex, 0u
-    %194:u32 = load %offset
-    store %193, %194
-    %195:ptr<storage, u32, read_write> = access %clusterLights, 1u, %tileIndex, 1u
-    %196:u32 = load %clusterLightCount
-    store %195, %196
-    ret
-  }
-}
-%tint_f32_to_u32 = func(%value:f32):u32 {
-  $B28: {
-    %198:u32 = convert %value
-    %199:bool = gte %value, 0.0f
-    %200:u32 = select 0u, %198, %199
-    %201:bool = lte %value, 4294967040.0f
-    %202:u32 = select 4294967295u, %200, %201
-    ret %202
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/benchmark/metaball-isosurface.wgsl.expected.ir.msl b/test/tint/benchmark/metaball-isosurface.wgsl.expected.ir.msl
deleted file mode 100644
index be43b04..0000000
--- a/test/tint/benchmark/metaball-isosurface.wgsl.expected.ir.msl
+++ /dev/null
@@ -1,664 +0,0 @@
-SKIP: FAILED
-
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: Tables = struct @align(4) {
-  edges:array<u32, 256> @offset(0)
-  tris:array<i32, 4096> @offset(1024)
-}
-
-IsosurfaceVolume = struct @align(16) {
-  min:vec3<f32> @offset(0)
-  max:vec3<f32> @offset(16)
-  step:vec3<f32> @offset(32)
-  size:vec3<u32> @offset(48)
-  threshold:f32 @offset(60)
-  values:array<f32> @offset(64)
-}
-
-PositionBuffer = struct @align(4) {
-  values:array<f32> @offset(0)
-}
-
-NormalBuffer = struct @align(4) {
-  values:array<f32> @offset(0)
-}
-
-IndexBuffer = struct @align(4) {
-  tris:array<u32> @offset(0)
-}
-
-DrawIndirectArgs = struct @align(4) {
-  vc:u32 @offset(0)
-  vertexCount:atomic<u32> @offset(4)
-  firstVertex:u32 @offset(8)
-  firstInstance:u32 @offset(12)
-  indexCount:atomic<u32> @offset(16)
-  indexedInstanceCount:u32 @offset(20)
-  indexedFirstIndex:u32 @offset(24)
-  indexedBaseVertex:u32 @offset(28)
-  indexedFirstInstance:u32 @offset(32)
-}
-
-$B1: {  # root
-  %tables:ptr<storage, Tables, read> = var @binding_point(0, 0)
-  %volume:ptr<storage, IsosurfaceVolume, read_write> = var @binding_point(0, 1)
-  %positionsOut:ptr<storage, PositionBuffer, read_write> = var @binding_point(0, 2)
-  %normalsOut:ptr<storage, NormalBuffer, read_write> = var @binding_point(0, 3)
-  %indicesOut:ptr<storage, IndexBuffer, read_write> = var @binding_point(0, 4)
-  %drawOut:ptr<storage, DrawIndirectArgs, read_write> = var @binding_point(0, 5)
-  %positions:ptr<private, array<vec3<f32>, 12>, read_write> = var
-  %normals:ptr<private, array<vec3<f32>, 12>, read_write> = var
-  %indices:ptr<private, array<u32, 12>, read_write> = var
-  %cubeVerts:ptr<private, u32, read_write> = var, 0u
-}
-
-%valueAt = func(%index:vec3<u32>):f32 {
-  $B2: {
-    %13:ptr<storage, vec3<u32>, read_write> = access %volume, 3u
-    %14:vec3<u32> = load %13
-    %15:vec3<bool> = gte %index, %14
-    %16:bool = any %15
-    if %16 [t: $B3] {  # if_1
-      $B3: {  # true
-        ret 0.0f
-      }
-    }
-    %17:u32 = access %index, 0u
-    %18:u32 = access %index, 1u
-    %19:ptr<storage, vec3<u32>, read_write> = access %volume, 3u
-    %20:u32 = load_vector_element %19, 0u
-    %21:u32 = mul %18, %20
-    %22:u32 = add %17, %21
-    %23:u32 = access %index, 2u
-    %24:ptr<storage, vec3<u32>, read_write> = access %volume, 3u
-    %25:u32 = load_vector_element %24, 0u
-    %26:u32 = mul %23, %25
-    %27:ptr<storage, vec3<u32>, read_write> = access %volume, 3u
-    %28:u32 = load_vector_element %27, 1u
-    %29:u32 = mul %26, %28
-    %30:u32 = add %22, %29
-    %valueIndex:u32 = let %30
-    %32:ptr<storage, f32, read_write> = access %volume, 5u, %valueIndex
-    %33:f32 = load %32
-    ret %33
-  }
-}
-%positionAt = func(%index_1:vec3<u32>):vec3<f32> {  # %index_1: 'index'
-  $B4: {
-    %36:ptr<storage, vec3<f32>, read_write> = access %volume, 0u
-    %37:vec3<f32> = load %36
-    %38:vec3<f32> = let %37
-    %39:ptr<storage, vec3<f32>, read_write> = access %volume, 2u
-    %40:vec3<f32> = load %39
-    %41:vec3<f32> = let %40
-    %42:vec3<u32> = swizzle %index_1, xyz
-    %43:vec3<f32> = convert %42
-    %44:vec3<f32> = mul %41, %43
-    %45:vec3<f32> = add %38, %44
-    ret %45
-  }
-}
-%normalAt = func(%index_2:vec3<u32>):vec3<f32> {  # %index_2: 'index'
-  $B5: {
-    %48:vec3<u32> = sub %index_2, vec3<u32>(1u, 0u, 0u)
-    %49:f32 = call %valueAt, %48
-    %50:f32 = let %49
-    %51:vec3<u32> = add %index_2, vec3<u32>(1u, 0u, 0u)
-    %52:f32 = call %valueAt, %51
-    %53:f32 = sub %50, %52
-    %54:f32 = let %53
-    %55:vec3<u32> = sub %index_2, vec3<u32>(0u, 1u, 0u)
-    %56:f32 = call %valueAt, %55
-    %57:f32 = let %56
-    %58:vec3<u32> = add %index_2, vec3<u32>(0u, 1u, 0u)
-    %59:f32 = call %valueAt, %58
-    %60:f32 = sub %57, %59
-    %61:f32 = let %60
-    %62:vec3<u32> = sub %index_2, vec3<u32>(0u, 0u, 1u)
-    %63:f32 = call %valueAt, %62
-    %64:f32 = let %63
-    %65:vec3<u32> = add %index_2, vec3<u32>(0u, 0u, 1u)
-    %66:f32 = call %valueAt, %65
-    %67:f32 = sub %64, %66
-    %68:vec3<f32> = construct %54, %61, %67
-    ret %68
-  }
-}
-%interpX = func(%index_3:u32, %i:vec3<u32>, %va:f32, %vb:f32):void {  # %index_3: 'index'
-  $B6: {
-    %74:ptr<storage, f32, read_write> = access %volume, 4u
-    %75:f32 = load %74
-    %76:f32 = sub %75, %va
-    %77:f32 = sub %vb, %va
-    %78:f32 = div %76, %77
-    %mu:f32 = let %78
-    %80:u32 = load %cubeVerts
-    %81:ptr<private, vec3<f32>, read_write> = access %positions, %80
-    %82:ptr<private, vec3<f32>, read_write> = let %81
-    %83:vec3<f32> = call %positionAt, %i
-    %84:vec3<f32> = let %83
-    %85:ptr<storage, vec3<f32>, read_write> = access %volume, 2u
-    %86:f32 = load_vector_element %85, 0u
-    %87:f32 = mul %86, %mu
-    %88:vec3<f32> = construct %87, 0.0f, 0.0f
-    %89:vec3<f32> = add %84, %88
-    store %82, %89
-    %90:vec3<f32> = call %normalAt, %i
-    %na:vec3<f32> = let %90
-    %92:vec3<u32> = add %i, vec3<u32>(1u, 0u, 0u)
-    %93:vec3<f32> = call %normalAt, %92
-    %nb:vec3<f32> = let %93
-    %95:u32 = load %cubeVerts
-    %96:ptr<private, vec3<f32>, read_write> = access %normals, %95
-    %97:ptr<private, vec3<f32>, read_write> = let %96
-    %98:vec3<f32> = construct %mu, %mu, %mu
-    %99:vec3<f32> = mix %na, %nb, %98
-    store %97, %99
-    %100:ptr<private, u32, read_write> = access %indices, %index_3
-    %101:u32 = load %cubeVerts
-    store %100, %101
-    %102:u32 = load %cubeVerts
-    %103:u32 = add %102, 1u
-    store %cubeVerts, %103
-    ret
-  }
-}
-%interpY = func(%index_4:u32, %i_1:vec3<u32>, %va_1:f32, %vb_1:f32):void {  # %index_4: 'index', %i_1: 'i', %va_1: 'va', %vb_1: 'vb'
-  $B7: {
-    %109:ptr<storage, f32, read_write> = access %volume, 4u
-    %110:f32 = load %109
-    %111:f32 = sub %110, %va_1
-    %112:f32 = sub %vb_1, %va_1
-    %113:f32 = div %111, %112
-    %mu_1:f32 = let %113  # %mu_1: 'mu'
-    %115:u32 = load %cubeVerts
-    %116:ptr<private, vec3<f32>, read_write> = access %positions, %115
-    %117:ptr<private, vec3<f32>, read_write> = let %116
-    %118:vec3<f32> = call %positionAt, %i_1
-    %119:vec3<f32> = let %118
-    %120:ptr<storage, vec3<f32>, read_write> = access %volume, 2u
-    %121:f32 = load_vector_element %120, 1u
-    %122:f32 = mul %121, %mu_1
-    %123:vec3<f32> = construct 0.0f, %122, 0.0f
-    %124:vec3<f32> = add %119, %123
-    store %117, %124
-    %125:vec3<f32> = call %normalAt, %i_1
-    %na_1:vec3<f32> = let %125  # %na_1: 'na'
-    %127:vec3<u32> = add %i_1, vec3<u32>(0u, 1u, 0u)
-    %128:vec3<f32> = call %normalAt, %127
-    %nb_1:vec3<f32> = let %128  # %nb_1: 'nb'
-    %130:u32 = load %cubeVerts
-    %131:ptr<private, vec3<f32>, read_write> = access %normals, %130
-    %132:ptr<private, vec3<f32>, read_write> = let %131
-    %133:vec3<f32> = construct %mu_1, %mu_1, %mu_1
-    %134:vec3<f32> = mix %na_1, %nb_1, %133
-    store %132, %134
-    %135:ptr<private, u32, read_write> = access %indices, %index_4
-    %136:u32 = load %cubeVerts
-    store %135, %136
-    %137:u32 = load %cubeVerts
-    %138:u32 = add %137, 1u
-    store %cubeVerts, %138
-    ret
-  }
-}
-%interpZ = func(%index_5:u32, %i_2:vec3<u32>, %va_2:f32, %vb_2:f32):void {  # %index_5: 'index', %i_2: 'i', %va_2: 'va', %vb_2: 'vb'
-  $B8: {
-    %144:ptr<storage, f32, read_write> = access %volume, 4u
-    %145:f32 = load %144
-    %146:f32 = sub %145, %va_2
-    %147:f32 = sub %vb_2, %va_2
-    %148:f32 = div %146, %147
-    %mu_2:f32 = let %148  # %mu_2: 'mu'
-    %150:u32 = load %cubeVerts
-    %151:ptr<private, vec3<f32>, read_write> = access %positions, %150
-    %152:ptr<private, vec3<f32>, read_write> = let %151
-    %153:vec3<f32> = call %positionAt, %i_2
-    %154:vec3<f32> = let %153
-    %155:ptr<storage, vec3<f32>, read_write> = access %volume, 2u
-    %156:f32 = load_vector_element %155, 2u
-    %157:f32 = mul %156, %mu_2
-    %158:vec3<f32> = construct 0.0f, 0.0f, %157
-    %159:vec3<f32> = add %154, %158
-    store %152, %159
-    %160:vec3<f32> = call %normalAt, %i_2
-    %na_2:vec3<f32> = let %160  # %na_2: 'na'
-    %162:vec3<u32> = add %i_2, vec3<u32>(0u, 0u, 1u)
-    %163:vec3<f32> = call %normalAt, %162
-    %nb_2:vec3<f32> = let %163  # %nb_2: 'nb'
-    %165:u32 = load %cubeVerts
-    %166:ptr<private, vec3<f32>, read_write> = access %normals, %165
-    %167:ptr<private, vec3<f32>, read_write> = let %166
-    %168:vec3<f32> = construct %mu_2, %mu_2, %mu_2
-    %169:vec3<f32> = mix %na_2, %nb_2, %168
-    store %167, %169
-    %170:ptr<private, u32, read_write> = access %indices, %index_5
-    %171:u32 = load %cubeVerts
-    store %170, %171
-    %172:u32 = load %cubeVerts
-    %173:u32 = add %172, 1u
-    store %cubeVerts, %173
-    ret
-  }
-}
-%computeMain = @compute @workgroup_size(4, 4, 4) func(%global_id:vec3<u32> [@global_invocation_id]):void {
-  $B9: {
-    %i0:vec3<u32> = let %global_id
-    %177:vec3<u32> = add %global_id, vec3<u32>(1u, 0u, 0u)
-    %i1:vec3<u32> = let %177
-    %179:vec3<u32> = add %global_id, vec3<u32>(1u, 1u, 0u)
-    %i2:vec3<u32> = let %179
-    %181:vec3<u32> = add %global_id, vec3<u32>(0u, 1u, 0u)
-    %i3:vec3<u32> = let %181
-    %183:vec3<u32> = add %global_id, vec3<u32>(0u, 0u, 1u)
-    %i4:vec3<u32> = let %183
-    %185:vec3<u32> = add %global_id, vec3<u32>(1u, 0u, 1u)
-    %i5:vec3<u32> = let %185
-    %187:vec3<u32> = add %global_id, vec3<u32>(1u)
-    %i6:vec3<u32> = let %187
-    %189:vec3<u32> = add %global_id, vec3<u32>(0u, 1u, 1u)
-    %i7:vec3<u32> = let %189
-    %191:f32 = call %valueAt, %i0
-    %v0:f32 = let %191
-    %193:f32 = call %valueAt, %i1
-    %v1:f32 = let %193
-    %195:f32 = call %valueAt, %i2
-    %v2:f32 = let %195
-    %197:f32 = call %valueAt, %i3
-    %v3:f32 = let %197
-    %199:f32 = call %valueAt, %i4
-    %v4:f32 = let %199
-    %201:f32 = call %valueAt, %i5
-    %v5:f32 = let %201
-    %203:f32 = call %valueAt, %i6
-    %v6:f32 = let %203
-    %205:f32 = call %valueAt, %i7
-    %v7:f32 = let %205
-    %cubeIndex:ptr<function, u32, read_write> = var, 0u
-    %208:ptr<storage, f32, read_write> = access %volume, 4u
-    %209:f32 = load %208
-    %210:bool = lt %v0, %209
-    if %210 [t: $B10] {  # if_2
-      $B10: {  # true
-        %211:u32 = load %cubeIndex
-        %212:u32 = or %211, 1u
-        store %cubeIndex, %212
-        exit_if  # if_2
-      }
-    }
-    %213:ptr<storage, f32, read_write> = access %volume, 4u
-    %214:f32 = load %213
-    %215:bool = lt %v1, %214
-    if %215 [t: $B11] {  # if_3
-      $B11: {  # true
-        %216:u32 = load %cubeIndex
-        %217:u32 = or %216, 2u
-        store %cubeIndex, %217
-        exit_if  # if_3
-      }
-    }
-    %218:ptr<storage, f32, read_write> = access %volume, 4u
-    %219:f32 = load %218
-    %220:bool = lt %v2, %219
-    if %220 [t: $B12] {  # if_4
-      $B12: {  # true
-        %221:u32 = load %cubeIndex
-        %222:u32 = or %221, 4u
-        store %cubeIndex, %222
-        exit_if  # if_4
-      }
-    }
-    %223:ptr<storage, f32, read_write> = access %volume, 4u
-    %224:f32 = load %223
-    %225:bool = lt %v3, %224
-    if %225 [t: $B13] {  # if_5
-      $B13: {  # true
-        %226:u32 = load %cubeIndex
-        %227:u32 = or %226, 8u
-        store %cubeIndex, %227
-        exit_if  # if_5
-      }
-    }
-    %228:ptr<storage, f32, read_write> = access %volume, 4u
-    %229:f32 = load %228
-    %230:bool = lt %v4, %229
-    if %230 [t: $B14] {  # if_6
-      $B14: {  # true
-        %231:u32 = load %cubeIndex
-        %232:u32 = or %231, 16u
-        store %cubeIndex, %232
-        exit_if  # if_6
-      }
-    }
-    %233:ptr<storage, f32, read_write> = access %volume, 4u
-    %234:f32 = load %233
-    %235:bool = lt %v5, %234
-    if %235 [t: $B15] {  # if_7
-      $B15: {  # true
-        %236:u32 = load %cubeIndex
-        %237:u32 = or %236, 32u
-        store %cubeIndex, %237
-        exit_if  # if_7
-      }
-    }
-    %238:ptr<storage, f32, read_write> = access %volume, 4u
-    %239:f32 = load %238
-    %240:bool = lt %v6, %239
-    if %240 [t: $B16] {  # if_8
-      $B16: {  # true
-        %241:u32 = load %cubeIndex
-        %242:u32 = or %241, 64u
-        store %cubeIndex, %242
-        exit_if  # if_8
-      }
-    }
-    %243:ptr<storage, f32, read_write> = access %volume, 4u
-    %244:f32 = load %243
-    %245:bool = lt %v7, %244
-    if %245 [t: $B17] {  # if_9
-      $B17: {  # true
-        %246:u32 = load %cubeIndex
-        %247:u32 = or %246, 128u
-        store %cubeIndex, %247
-        exit_if  # if_9
-      }
-    }
-    %248:u32 = load %cubeIndex
-    %249:ptr<storage, u32, read> = access %tables, 0u, %248
-    %250:u32 = load %249
-    %edges:u32 = let %250
-    %252:u32 = and %edges, 1u
-    %253:bool = neq %252, 0u
-    if %253 [t: $B18] {  # if_10
-      $B18: {  # true
-        %254:void = call %interpX, 0u, %i0, %v0, %v1
-        exit_if  # if_10
-      }
-    }
-    %255:u32 = and %edges, 2u
-    %256:bool = neq %255, 0u
-    if %256 [t: $B19] {  # if_11
-      $B19: {  # true
-        %257:void = call %interpY, 1u, %i1, %v1, %v2
-        exit_if  # if_11
-      }
-    }
-    %258:u32 = and %edges, 4u
-    %259:bool = neq %258, 0u
-    if %259 [t: $B20] {  # if_12
-      $B20: {  # true
-        %260:void = call %interpX, 2u, %i3, %v3, %v2
-        exit_if  # if_12
-      }
-    }
-    %261:u32 = and %edges, 8u
-    %262:bool = neq %261, 0u
-    if %262 [t: $B21] {  # if_13
-      $B21: {  # true
-        %263:void = call %interpY, 3u, %i0, %v0, %v3
-        exit_if  # if_13
-      }
-    }
-    %264:u32 = and %edges, 16u
-    %265:bool = neq %264, 0u
-    if %265 [t: $B22] {  # if_14
-      $B22: {  # true
-        %266:void = call %interpX, 4u, %i4, %v4, %v5
-        exit_if  # if_14
-      }
-    }
-    %267:u32 = and %edges, 32u
-    %268:bool = neq %267, 0u
-    if %268 [t: $B23] {  # if_15
-      $B23: {  # true
-        %269:void = call %interpY, 5u, %i5, %v5, %v6
-        exit_if  # if_15
-      }
-    }
-    %270:u32 = and %edges, 64u
-    %271:bool = neq %270, 0u
-    if %271 [t: $B24] {  # if_16
-      $B24: {  # true
-        %272:void = call %interpX, 6u, %i7, %v7, %v6
-        exit_if  # if_16
-      }
-    }
-    %273:u32 = and %edges, 128u
-    %274:bool = neq %273, 0u
-    if %274 [t: $B25] {  # if_17
-      $B25: {  # true
-        %275:void = call %interpY, 7u, %i4, %v4, %v7
-        exit_if  # if_17
-      }
-    }
-    %276:u32 = and %edges, 256u
-    %277:bool = neq %276, 0u
-    if %277 [t: $B26] {  # if_18
-      $B26: {  # true
-        %278:void = call %interpZ, 8u, %i0, %v0, %v4
-        exit_if  # if_18
-      }
-    }
-    %279:u32 = and %edges, 512u
-    %280:bool = neq %279, 0u
-    if %280 [t: $B27] {  # if_19
-      $B27: {  # true
-        %281:void = call %interpZ, 9u, %i1, %v1, %v5
-        exit_if  # if_19
-      }
-    }
-    %282:u32 = and %edges, 1024u
-    %283:bool = neq %282, 0u
-    if %283 [t: $B28] {  # if_20
-      $B28: {  # true
-        %284:void = call %interpZ, 10u, %i2, %v2, %v6
-        exit_if  # if_20
-      }
-    }
-    %285:u32 = and %edges, 2048u
-    %286:bool = neq %285, 0u
-    if %286 [t: $B29] {  # if_21
-      $B29: {  # true
-        %287:void = call %interpZ, 11u, %i3, %v3, %v7
-        exit_if  # if_21
-      }
-    }
-    %288:u32 = load %cubeIndex
-    %289:u32 = and 4u, 31u
-    %290:u32 = shl %288, %289
-    %291:u32 = add %290, 1u
-    %triTableOffset:u32 = let %291
-    %293:u32 = sub %triTableOffset, 1u
-    %294:ptr<storage, i32, read> = access %tables, 1u, %293
-    %295:i32 = load %294
-    %296:u32 = convert %295
-    %indexCount:u32 = let %296
-    %298:ptr<storage, atomic<u32>, read_write> = access %drawOut, 1u
-    %299:u32 = load %cubeVerts
-    %300:u32 = atomicAdd %298, %299
-    %firstVertex:ptr<function, u32, read_write> = var, %300
-    %302:u32 = access %global_id, 0u
-    %303:u32 = access %global_id, 1u
-    %304:ptr<storage, vec3<u32>, read_write> = access %volume, 3u
-    %305:u32 = load_vector_element %304, 0u
-    %306:u32 = mul %303, %305
-    %307:u32 = add %302, %306
-    %308:u32 = access %global_id, 2u
-    %309:ptr<storage, vec3<u32>, read_write> = access %volume, 3u
-    %310:u32 = load_vector_element %309, 0u
-    %311:u32 = mul %308, %310
-    %312:ptr<storage, vec3<u32>, read_write> = access %volume, 3u
-    %313:u32 = load_vector_element %312, 1u
-    %314:u32 = mul %311, %313
-    %315:u32 = add %307, %314
-    %bufferOffset:u32 = let %315
-    %317:u32 = mul %bufferOffset, 15u
-    %firstIndex:u32 = let %317
-    loop [i: $B30, b: $B31, c: $B32] {  # loop_1
-      $B30: {  # initializer
-        %i_3:ptr<function, u32, read_write> = var, 0u  # %i_3: 'i'
-        next_iteration  # -> $B31
-      }
-      $B31: {  # body
-        %320:u32 = load %i_3
-        %321:u32 = load %cubeVerts
-        %322:bool = lt %320, %321
-        if %322 [t: $B33, f: $B34] {  # if_22
-          $B33: {  # true
-            exit_if  # if_22
-          }
-          $B34: {  # false
-            exit_loop  # loop_1
-          }
-        }
-        %323:u32 = load %firstVertex
-        %324:u32 = mul %323, 3u
-        %325:u32 = load %i_3
-        %326:u32 = mul %325, 3u
-        %327:u32 = add %324, %326
-        %328:ptr<storage, f32, read_write> = access %positionsOut, 0u, %327
-        %329:u32 = load %i_3
-        %330:ptr<private, vec3<f32>, read_write> = access %positions, %329
-        %331:f32 = load_vector_element %330, 0u
-        store %328, %331
-        %332:u32 = load %firstVertex
-        %333:u32 = mul %332, 3u
-        %334:u32 = load %i_3
-        %335:u32 = mul %334, 3u
-        %336:u32 = add %333, %335
-        %337:u32 = add %336, 1u
-        %338:ptr<storage, f32, read_write> = access %positionsOut, 0u, %337
-        %339:u32 = load %i_3
-        %340:ptr<private, vec3<f32>, read_write> = access %positions, %339
-        %341:f32 = load_vector_element %340, 1u
-        store %338, %341
-        %342:u32 = load %firstVertex
-        %343:u32 = mul %342, 3u
-        %344:u32 = load %i_3
-        %345:u32 = mul %344, 3u
-        %346:u32 = add %343, %345
-        %347:u32 = add %346, 2u
-        %348:ptr<storage, f32, read_write> = access %positionsOut, 0u, %347
-        %349:u32 = load %i_3
-        %350:ptr<private, vec3<f32>, read_write> = access %positions, %349
-        %351:f32 = load_vector_element %350, 2u
-        store %348, %351
-        %352:u32 = load %firstVertex
-        %353:u32 = mul %352, 3u
-        %354:u32 = load %i_3
-        %355:u32 = mul %354, 3u
-        %356:u32 = add %353, %355
-        %357:ptr<storage, f32, read_write> = access %normalsOut, 0u, %356
-        %358:u32 = load %i_3
-        %359:ptr<private, vec3<f32>, read_write> = access %normals, %358
-        %360:f32 = load_vector_element %359, 0u
-        store %357, %360
-        %361:u32 = load %firstVertex
-        %362:u32 = mul %361, 3u
-        %363:u32 = load %i_3
-        %364:u32 = mul %363, 3u
-        %365:u32 = add %362, %364
-        %366:u32 = add %365, 1u
-        %367:ptr<storage, f32, read_write> = access %normalsOut, 0u, %366
-        %368:u32 = load %i_3
-        %369:ptr<private, vec3<f32>, read_write> = access %normals, %368
-        %370:f32 = load_vector_element %369, 1u
-        store %367, %370
-        %371:u32 = load %firstVertex
-        %372:u32 = mul %371, 3u
-        %373:u32 = load %i_3
-        %374:u32 = mul %373, 3u
-        %375:u32 = add %372, %374
-        %376:u32 = add %375, 2u
-        %377:ptr<storage, f32, read_write> = access %normalsOut, 0u, %376
-        %378:u32 = load %i_3
-        %379:ptr<private, vec3<f32>, read_write> = access %normals, %378
-        %380:f32 = load_vector_element %379, 2u
-        store %377, %380
-        continue  # -> $B32
-      }
-      $B32: {  # continuing
-        %381:u32 = load %i_3
-        %382:u32 = add %381, 1u
-        store %i_3, %382
-        next_iteration  # -> $B31
-      }
-    }
-    loop [i: $B35, b: $B36, c: $B37] {  # loop_2
-      $B35: {  # initializer
-        %i_4:ptr<function, u32, read_write> = var, 0u  # %i_4: 'i'
-        next_iteration  # -> $B36
-      }
-      $B36: {  # body
-        %384:u32 = load %i_4
-        %385:bool = lt %384, %indexCount
-        if %385 [t: $B38, f: $B39] {  # if_23
-          $B38: {  # true
-            exit_if  # if_23
-          }
-          $B39: {  # false
-            exit_loop  # loop_2
-          }
-        }
-        %386:u32 = load %i_4
-        %387:u32 = add %triTableOffset, %386
-        %388:ptr<storage, i32, read> = access %tables, 1u, %387
-        %389:i32 = load %388
-        %index_6:i32 = let %389  # %index_6: 'index'
-        %391:u32 = load %i_4
-        %392:u32 = add %firstIndex, %391
-        %393:ptr<storage, u32, read_write> = access %indicesOut, 0u, %392
-        %394:u32 = load %firstVertex
-        %395:ptr<private, u32, read_write> = access %indices, %index_6
-        %396:u32 = load %395
-        %397:u32 = add %394, %396
-        store %393, %397
-        continue  # -> $B37
-      }
-      $B37: {  # continuing
-        %398:u32 = load %i_4
-        %399:u32 = add %398, 1u
-        store %i_4, %399
-        next_iteration  # -> $B36
-      }
-    }
-    loop [i: $B40, b: $B41, c: $B42] {  # loop_3
-      $B40: {  # initializer
-        %i_5:ptr<function, u32, read_write> = var, %indexCount  # %i_5: 'i'
-        next_iteration  # -> $B41
-      }
-      $B41: {  # body
-        %401:u32 = load %i_5
-        %402:bool = lt %401, 15u
-        if %402 [t: $B43, f: $B44] {  # if_24
-          $B43: {  # true
-            exit_if  # if_24
-          }
-          $B44: {  # false
-            exit_loop  # loop_3
-          }
-        }
-        %403:u32 = load %i_5
-        %404:u32 = add %firstIndex, %403
-        %405:ptr<storage, u32, read_write> = access %indicesOut, 0u, %404
-        %406:u32 = load %firstVertex
-        store %405, %406
-        continue  # -> $B42
-      }
-      $B42: {  # continuing
-        %407:u32 = load %i_5
-        %408:u32 = add %407, 1u
-        store %i_5, %408
-        next_iteration  # -> $B41
-      }
-    }
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/bug/tint/2010.spvasm.expected.ir.msl b/test/tint/bug/tint/2010.spvasm.expected.ir.msl
index 252583d..ffc59d5 100644
--- a/test/tint/bug/tint/2010.spvasm.expected.ir.msl
+++ b/test/tint/bug/tint/2010.spvasm.expected.ir.msl
@@ -1,271 +1,168 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+template<typename T, size_t N>
+struct tint_array {
+  const constant T& operator[](size_t i) const constant { return elements[i]; }
+  device T& operator[](size_t i) device { return elements[i]; }
+  const device T& operator[](size_t i) const device { return elements[i]; }
+  thread T& operator[](size_t i) thread { return elements[i]; }
+  const thread T& operator[](size_t i) const thread { return elements[i]; }
+  threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+  const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+  T elements[N];
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: S = struct @align(8) {
-  field0:vec2<f32> @offset(0)
-  field1:u32 @offset(8)
-}
+struct S {
+  float2 field0;
+  uint field1;
+};
+struct S_1 {
+  uint field0;
+};
+struct S_2 {
+  S_1 field0;
+};
+struct S_3 {
+  tint_array<float4, 1> field0;
+};
+struct S_4 {
+  tint_array<float4, 1> field0;
+};
+struct tint_module_vars_struct {
+  threadgroup tint_array<S, 4096>* x_28;
+  threadgroup atomic_uint* x_34;
+  threadgroup atomic_uint* x_35;
+  threadgroup atomic_uint* x_36;
+  threadgroup atomic_uint* x_37;
+  thread uint3* x_3;
+  const constant S_2* x_6;
+  const device S_3* x_9;
+  device S_4* x_12;
+};
+struct tint_symbol_6 {
+  tint_array<S, 4096> tint_symbol_1;
+  atomic_uint tint_symbol_2;
+  atomic_uint tint_symbol_3;
+  atomic_uint tint_symbol_4;
+  atomic_uint tint_symbol_5;
+};
 
-S_1 = struct @align(4) {
-  field0:u32 @offset(0)
-}
-
-S_2 = struct @align(4) {
-  field0:S_1 @offset(0)
-}
-
-S_3 = struct @align(16) {
-  field0:array<vec4<f32>> @offset(0)
-}
-
-S_4 = struct @align(16) {
-  field0:array<vec4<f32>> @offset(0)
-}
-
-$B1: {  # root
-  %x_28:ptr<workgroup, array<S, 4096>, read_write> = var
-  %x_34:ptr<workgroup, atomic<u32>, read_write> = var
-  %x_35:ptr<workgroup, atomic<u32>, read_write> = var
-  %x_36:ptr<workgroup, atomic<u32>, read_write> = var
-  %x_37:ptr<workgroup, atomic<u32>, read_write> = var
-  %x_3:ptr<private, vec3<u32>, read_write> = var
-  %x_6:ptr<uniform, S_2, read> = var @binding_point(0, 1)
-  %x_9:ptr<storage, S_3, read> = var @binding_point(0, 2)
-  %x_12:ptr<storage, S_4, read_write> = var @binding_point(0, 3)
-}
-
-%main_1 = func():void {
-  $B2: {
-    %x_54:ptr<function, u32, read_write> = var
-    %x_58:ptr<function, u32, read_write> = var
-    %x_85:ptr<function, vec4<f32>, read_write> = var
-    %x_88:ptr<function, u32, read_write> = var
-    %15:u32 = load_vector_element %x_3, 0u
-    %x_52:u32 = let %15
-    store %x_54, 0u
-    loop [b: $B3, c: $B4] {  # loop_1
-      $B3: {  # body
-        %x_55:ptr<function, u32, read_write> = var
-        %18:ptr<uniform, u32, read> = access %x_6, 0u, 0u
-        %19:u32 = load %18
-        store %x_58, %19
-        %20:u32 = load %x_54
-        %21:u32 = load %x_58
-        %22:bool = lt %20, %21
-        if %22 [t: $B5, f: $B6] {  # if_1
-          $B5: {  # true
-            exit_if  # if_1
-          }
-          $B6: {  # false
-            exit_loop  # loop_1
-          }
-        }
-        %23:u32 = load %x_54
-        %24:u32 = add %23, %x_52
-        %x_62:u32 = let %24
-        %26:u32 = load %x_58
-        %27:bool = gte %x_62, %26
-        if %27 [t: $B7] {  # if_2
-          $B7: {  # true
-            %28:ptr<storage, vec4<f32>, read> = access %x_9, 0u, %x_62
-            %29:vec4<f32> = load %28
-            %x_67:vec4<f32> = let %29
-            %31:ptr<workgroup, S, read_write> = access %x_28, %x_62
-            %32:vec2<f32> = swizzle %x_67, xy
-            %33:vec2<f32> = swizzle %x_67, zw
-            %34:vec2<f32> = add %32, %33
-            %35:vec2<f32> = mul %34, 0.5f
-            %36:S = construct %35, %x_62
-            store %31, %36
-            exit_if  # if_2
-          }
-        }
-        continue  # -> $B4
+void main_1(tint_module_vars_struct tint_module_vars) {
+  uint x_54 = 0u;
+  uint x_58 = 0u;
+  float4 x_85 = 0.0f;
+  uint x_88 = 0u;
+  uint const x_52 = (*tint_module_vars.x_3)[0u];
+  x_54 = 0u;
+  {
+    while(true) {
+      uint x_55 = 0u;
+      x_58 = (*tint_module_vars.x_6).field0.field0;
+      if ((x_54 < x_58)) {
+      } else {
+        break;
       }
-      $B4: {  # continuing
-        %37:u32 = load %x_54
-        %38:u32 = add %37, 32u
-        store %x_55, %38
-        %39:u32 = load %x_55
-        store %x_54, %39
-        next_iteration  # -> $B3
+      uint const x_62 = (x_54 + x_52);
+      if ((x_62 >= x_58)) {
+        float4 const x_67 = (*tint_module_vars.x_9).field0[x_62];
+        (*tint_module_vars.x_28)[x_62] = S{.field0=((x_67.xy + x_67.zw) * 0.5f), .field1=x_62};
       }
+      {
+        x_55 = (x_54 + 32u);
+        x_54 = x_55;
+      }
+      continue;
     }
-    %40:void = msl.threadgroup_barrier 4u
-    %41:u32 = load %x_58
-    %42:i32 = bitcast %41
-    %x_74:i32 = let %42
-    %44:ptr<workgroup, vec2<f32>, read_write> = access %x_28, 0i, 0u
-    %45:vec2<f32> = load %44
-    %x_76:vec2<f32> = let %45
-    %47:bool = eq %x_52, 0u
-    if %47 [t: $B8] {  # if_3
-      $B8: {  # true
-        %48:vec2<u32> = bitcast %x_76
-        %x_80:vec2<u32> = let %48
-        %50:u32 = access %x_80, 0u
-        %x_81:u32 = let %50
-        %52:void = atomicStore %x_34, %x_81
-        %53:u32 = access %x_80, 1u
-        %x_82:u32 = let %53
-        %55:void = atomicStore %x_35, %x_82
-        %56:void = atomicStore %x_36, %x_81
-        %57:void = atomicStore %x_37, %x_82
-        exit_if  # if_3
-      }
-    }
-    %58:vec4<f32> = swizzle %x_76, xyxy
-    store %x_85, %58
-    store %x_88, 1u
-    loop [b: $B9, c: $B10] {  # loop_2
-      $B9: {  # body
-        %x_111:ptr<function, vec4<f32>, read_write> = var
-        %x_86:ptr<function, vec4<f32>, read_write> = var
-        %x_89:ptr<function, u32, read_write> = var
-        %62:u32 = bitcast %x_74
-        %x_90:u32 = let %62
-        %64:u32 = load %x_88
-        %65:bool = lt %64, %x_90
-        if %65 [t: $B11, f: $B12] {  # if_4
-          $B11: {  # true
-            exit_if  # if_4
-          }
-          $B12: {  # false
-            exit_loop  # loop_2
-          }
-        }
-        %66:u32 = load %x_88
-        %67:u32 = add %66, %x_52
-        %x_94:u32 = let %67
-        %69:vec4<f32> = load %x_85
-        store %x_86, %69
-        %70:bool = gte %x_94, %x_90
-        if %70 [t: $B13] {  # if_5
-          $B13: {  # true
-            %71:ptr<workgroup, vec2<f32>, read_write> = access %x_28, %x_94, 0u
-            %72:vec2<f32> = load %71
-            %x_99:vec2<f32> = let %72
-            %74:vec4<f32> = load %x_85
-            %75:vec2<f32> = swizzle %74, xy
-            %76:vec2<f32> = min %75, %x_99
-            %x_101:vec2<f32> = let %76
-            %78:vec4<f32> = load %x_85
-            %x_103_1:ptr<function, vec4<f32>, read_write> = var, %78
-            %80:f32 = access %x_101, 0u
-            store_vector_element %x_103_1, 0u, %80
-            %81:vec4<f32> = load %x_103_1
-            %x_103:vec4<f32> = let %81
-            %x_105_1:ptr<function, vec4<f32>, read_write> = var, %x_103
-            %84:f32 = access %x_101, 1u
-            store_vector_element %x_105_1, 1u, %84
-            %85:vec4<f32> = load %x_105_1
-            %x_105:vec4<f32> = let %85
-            %87:vec4<f32> = load %x_105_1
-            %88:vec2<f32> = swizzle %87, zw
-            %89:vec2<f32> = max %88, %x_99
-            %x_107:vec2<f32> = let %89
-            %x_109_1:ptr<function, vec4<f32>, read_write> = var, %x_105
-            %92:f32 = access %x_107, 0u
-            store_vector_element %x_109_1, 2u, %92
-            %93:vec4<f32> = load %x_109_1
-            store %x_111, %93
-            %94:f32 = access %x_107, 1u
-            store_vector_element %x_111, 3u, %94
-            %95:vec4<f32> = load %x_111
-            store %x_86, %95
-            exit_if  # if_5
-          }
-        }
-        continue  # -> $B10
-      }
-      $B10: {  # continuing
-        %96:u32 = load %x_88
-        %97:u32 = add %96, 32u
-        store %x_89, %97
-        %98:vec4<f32> = load %x_86
-        store %x_85, %98
-        %99:u32 = load %x_89
-        store %x_88, %99
-        next_iteration  # -> $B9
-      }
-    }
-    %100:void = msl.threadgroup_barrier 4u
-    %101:f32 = load_vector_element %x_85, 0u
-    %102:u32 = bitcast %101
-    %103:u32 = atomicMin %x_34, %102
-    %x_114:u32 = let %103
-    %105:f32 = load_vector_element %x_85, 1u
-    %106:u32 = bitcast %105
-    %107:u32 = atomicMin %x_35, %106
-    %x_117:u32 = let %107
-    %109:f32 = load_vector_element %x_85, 2u
-    %110:u32 = bitcast %109
-    %111:u32 = atomicMax %x_36, %110
-    %x_120:u32 = let %111
-    %113:f32 = load_vector_element %x_85, 3u
-    %114:u32 = bitcast %113
-    %115:u32 = atomicMax %x_37, %114
-    %x_123:u32 = let %115
-    %117:void = msl.threadgroup_barrier 4u
-    %118:ptr<storage, vec4<f32>, read_write> = access %x_12, 0u, 0i
-    %119:u32 = atomicLoad %x_34
-    %120:f32 = bitcast %119
-    %121:f32 = let %120
-    %122:u32 = atomicLoad %x_35
-    %123:f32 = bitcast %122
-    %124:f32 = let %123
-    %125:u32 = atomicLoad %x_36
-    %126:f32 = bitcast %125
-    %127:f32 = let %126
-    %128:u32 = atomicLoad %x_37
-    %129:f32 = bitcast %128
-    %130:vec4<f32> = construct %121, %124, %127, %129
-    store %118, %130
-    ret
   }
-}
-%tint_symbol = @compute @workgroup_size(32, 1, 1) func(%x_3_param:vec3<u32> [@local_invocation_id], %tint_local_index:u32 [@local_invocation_index]):void {
-  $B14: {
-    %134:bool = eq %tint_local_index, 0u
-    if %134 [t: $B15] {  # if_6
-      $B15: {  # true
-        %135:void = atomicStore %x_34, 0u
-        %136:void = atomicStore %x_35, 0u
-        %137:void = atomicStore %x_36, 0u
-        %138:void = atomicStore %x_37, 0u
-        exit_if  # if_6
-      }
-    }
-    loop [i: $B16, b: $B17, c: $B18] {  # loop_3
-      $B16: {  # initializer
-        next_iteration %tint_local_index  # -> $B17
-      }
-      $B17 (%idx:u32): {  # body
-        %140:bool = gte %idx, 4096u
-        if %140 [t: $B19] {  # if_7
-          $B19: {  # true
-            exit_loop  # loop_3
-          }
-        }
-        %141:ptr<workgroup, S, read_write> = access %x_28, %idx
-        store %141, S(vec2<f32>(0.0f), 0u)
-        continue  # -> $B18
-      }
-      $B18: {  # continuing
-        %142:u32 = add %idx, 32u
-        next_iteration %142  # -> $B17
-      }
-    }
-    %143:void = msl.threadgroup_barrier 4u
-    store %x_3, %x_3_param
-    %144:void = call %main_1
-    ret
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  int const x_74 = as_type<int>(x_58);
+  float2 const x_76 = (*tint_module_vars.x_28)[0].field0;
+  if ((x_52 == 0u)) {
+    uint2 const x_80 = as_type<uint2>(x_76);
+    uint const x_81 = x_80[0u];
+    atomic_store_explicit(tint_module_vars.x_34, x_81, memory_order_relaxed);
+    uint const x_82 = x_80[1u];
+    atomic_store_explicit(tint_module_vars.x_35, x_82, memory_order_relaxed);
+    atomic_store_explicit(tint_module_vars.x_36, x_81, memory_order_relaxed);
+    atomic_store_explicit(tint_module_vars.x_37, x_82, memory_order_relaxed);
   }
+  x_85 = x_76.xyxy;
+  x_88 = 1u;
+  {
+    while(true) {
+      float4 x_111 = 0.0f;
+      float4 x_86 = 0.0f;
+      uint x_89 = 0u;
+      uint const x_90 = as_type<uint>(x_74);
+      if ((x_88 < x_90)) {
+      } else {
+        break;
+      }
+      uint const x_94 = (x_88 + x_52);
+      x_86 = x_85;
+      if ((x_94 >= x_90)) {
+        float2 const x_99 = (*tint_module_vars.x_28)[x_94].field0;
+        float2 const x_101 = min(x_85.xy, x_99);
+        float4 x_103_1 = x_85;
+        x_103_1[0u] = x_101[0u];
+        float4 const x_103 = x_103_1;
+        float4 x_105_1 = x_103;
+        x_105_1[1u] = x_101[1u];
+        float4 const x_105 = x_105_1;
+        float2 const x_107 = max(x_105_1.zw, x_99);
+        float4 x_109_1 = x_105;
+        x_109_1[2u] = x_107[0u];
+        x_111 = x_109_1;
+        x_111[3u] = x_107[1u];
+        x_86 = x_111;
+      }
+      {
+        x_89 = (x_88 + 32u);
+        x_85 = x_86;
+        x_88 = x_89;
+      }
+      continue;
+    }
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  uint const x_114 = atomic_fetch_min_explicit(tint_module_vars.x_34, as_type<uint>(x_85[0u]), memory_order_relaxed);
+  uint const x_117 = atomic_fetch_min_explicit(tint_module_vars.x_35, as_type<uint>(x_85[1u]), memory_order_relaxed);
+  uint const x_120 = atomic_fetch_max_explicit(tint_module_vars.x_36, as_type<uint>(x_85[2u]), memory_order_relaxed);
+  uint const x_123 = atomic_fetch_max_explicit(tint_module_vars.x_37, as_type<uint>(x_85[3u]), memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  float const v = as_type<float>(atomic_load_explicit(tint_module_vars.x_34, memory_order_relaxed));
+  float const v_1 = as_type<float>(atomic_load_explicit(tint_module_vars.x_35, memory_order_relaxed));
+  float const v_2 = as_type<float>(atomic_load_explicit(tint_module_vars.x_36, memory_order_relaxed));
+  (*tint_module_vars.x_12).field0[0] = float4(v, v_1, v_2, as_type<float>(atomic_load_explicit(tint_module_vars.x_37, memory_order_relaxed)));
 }
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void tint_symbol_inner(uint3 x_3_param, uint tint_local_index, tint_module_vars_struct tint_module_vars) {
+  if ((tint_local_index == 0u)) {
+    atomic_store_explicit(tint_module_vars.x_34, 0u, memory_order_relaxed);
+    atomic_store_explicit(tint_module_vars.x_35, 0u, memory_order_relaxed);
+    atomic_store_explicit(tint_module_vars.x_36, 0u, memory_order_relaxed);
+    atomic_store_explicit(tint_module_vars.x_37, 0u, memory_order_relaxed);
+  }
+  {
+    uint v_3 = 0u;
+    v_3 = tint_local_index;
+    while(true) {
+      uint const v_4 = v_3;
+      if ((v_4 >= 4096u)) {
+        break;
+      }
+      (*tint_module_vars.x_28)[v_4] = S{};
+      {
+        v_3 = (v_4 + 32u);
+      }
+      continue;
+    }
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.x_3) = x_3_param;
+  main_1(tint_module_vars);
+}
+kernel void tint_symbol(uint3 x_3_param [[thread_position_in_threadgroup]], uint tint_local_index [[thread_index_in_threadgroup]], threadgroup tint_symbol_6* v_5 [[threadgroup(0)]], const constant S_2* x_6 [[buffer(1)]], const device S_3* x_9 [[buffer(2)]], device S_4* x_12 [[buffer(3)]]) {
+  thread uint3 x_3 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.x_28=(&(*v_5).tint_symbol_1), .x_34=(&(*v_5).tint_symbol_2), .x_35=(&(*v_5).tint_symbol_3), .x_36=(&(*v_5).tint_symbol_4), .x_37=(&(*v_5).tint_symbol_5), .x_3=(&x_3), .x_6=x_6, .x_9=x_9, .x_12=x_12};
+  tint_symbol_inner(x_3_param, tint_local_index, tint_module_vars);
+}
diff --git a/test/tint/bug/tint/2063.wgsl.expected.ir.msl b/test/tint/bug/tint/2063.wgsl.expected.ir.msl
index 92c0fdd..b89c2c3 100644
--- a/test/tint/bug/tint/2063.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/2063.wgsl.expected.ir.msl
@@ -1,9 +1,20 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  threadgroup atomic_int* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_int tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicStore
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void compute_main_inner(uint tint_local_index, tint_module_vars_struct tint_module_vars) {
+  if ((tint_local_index == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  int res = atomic_fetch_sub_explicit(tint_module_vars.arg_0, -1, memory_order_relaxed);
+}
+kernel void compute_main(uint tint_local_index [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=(&(*v).tint_symbol)};
+  compute_main_inner(tint_local_index, tint_module_vars);
+}
diff --git a/test/tint/bug/tint/926.wgsl.expected.ir.msl b/test/tint/bug/tint/926.wgsl.expected.ir.msl
index 4ee0699..73e416f 100644
--- a/test/tint/bug/tint/926.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/926.wgsl.expected.ir.msl
@@ -1,28 +1,18 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct DrawIndirectArgs {
+  atomic_uint vertexCount;
+};
+struct tint_module_vars_struct {
+  device DrawIndirectArgs* drawOut;
+  thread uint* cubeVerts;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: DrawIndirectArgs = struct @align(4) {
-  vertexCount:atomic<u32> @offset(0)
+void computeMain_inner(uint3 global_id, tint_module_vars_struct tint_module_vars) {
+  uint const firstVertex = atomic_fetch_add_explicit((&(*tint_module_vars.drawOut).vertexCount), (*tint_module_vars.cubeVerts), memory_order_relaxed);
 }
-
-$B1: {  # root
-  %drawOut:ptr<storage, DrawIndirectArgs, read_write> = var @binding_point(0, 5)
-  %cubeVerts:ptr<private, u32, read_write> = var, 0u
+kernel void computeMain(uint3 global_id [[thread_position_in_grid]], device DrawIndirectArgs* drawOut [[buffer(5)]]) {
+  thread uint cubeVerts = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.drawOut=drawOut, .cubeVerts=(&cubeVerts)};
+  computeMain_inner(global_id, tint_module_vars);
 }
-
-%computeMain = @compute @workgroup_size(1, 1, 1) func(%global_id:vec3<u32> [@global_invocation_id]):void {
-  $B2: {
-    %5:ptr<storage, atomic<u32>, read_write> = access %drawOut, 0u
-    %6:u32 = load %cubeVerts
-    %7:u32 = atomicAdd %5, %6
-    %firstVertex:u32 = let %7
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.ir.msl b/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.ir.msl
index 92c0fdd..7a49714 100644
--- a/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.ir.msl
@@ -1,9 +1,81 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+template<typename T, size_t N>
+struct tint_array {
+  const constant T& operator[](size_t i) const constant { return elements[i]; }
+  device T& operator[](size_t i) device { return elements[i]; }
+  const device T& operator[](size_t i) const device { return elements[i]; }
+  thread T& operator[](size_t i) thread { return elements[i]; }
+  const thread T& operator[](size_t i) const thread { return elements[i]; }
+  threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+  const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+  T elements[N];
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicStore
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* wg;
+};
+struct tint_symbol_1 {
+  tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3> tint_symbol;
+};
+
+uint tint_mod_u32(uint lhs, uint rhs) {
+  uint const v = select(rhs, 1u, (rhs == 0u));
+  return (lhs - ((lhs / v) * v));
+}
+uint tint_div_u32(uint lhs, uint rhs) {
+  return (lhs / select(rhs, 1u, (rhs == 0u)));
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  uint idx = 0u;
+  idx = local_invocation_index_2;
+  {
+    while(true) {
+      if (!((idx < 6u))) {
+        break;
+      }
+      uint const x_31 = idx;
+      uint const x_33 = idx;
+      uint const x_35 = idx;
+      uint const v_1 = tint_div_u32(x_31, 2u);
+      uint const v_2 = tint_mod_u32(x_33, 2u);
+      atomic_store_explicit((&(*tint_module_vars.wg)[v_1][v_2][tint_mod_u32(x_35, 1u)]), 0u, memory_order_relaxed);
+      {
+        idx = (idx + 1u);
+      }
+      continue;
+    }
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomic_store_explicit((&(*tint_module_vars.wg)[2][1][0]), 1u, memory_order_relaxed);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_57 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_57, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  {
+    uint v_3 = 0u;
+    v_3 = local_invocation_index_1_param;
+    while(true) {
+      uint const v_4 = v_3;
+      if ((v_4 >= 6u)) {
+        break;
+      }
+      atomic_store_explicit((&(*tint_module_vars.wg)[(v_4 / 2u)][(v_4 % 2u)][0u]), 0u, memory_order_relaxed);
+      {
+        v_3 = (v_4 + 1u);
+      }
+      continue;
+    }
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v_5 [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .wg=(&(*v_5).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.ir.msl b/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.ir.msl
index 3fa6a4b..298f1ab 100644
--- a/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.ir.msl
+++ b/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.ir.msl
@@ -1,9 +1,44 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+template<typename T, size_t N>
+struct tint_array {
+  const constant T& operator[](size_t i) const constant { return elements[i]; }
+  device T& operator[](size_t i) device { return elements[i]; }
+  const device T& operator[](size_t i) const device { return elements[i]; }
+  thread T& operator[](size_t i) thread { return elements[i]; }
+  const thread T& operator[](size_t i) const thread { return elements[i]; }
+  threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+  const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+  T elements[N];
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:388 internal compiler error: Switch() matched no cases. Type: tint::core::ir::BlockParam
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+struct tint_module_vars_struct {
+  threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* wg;
+};
+struct tint_symbol_1 {
+  tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3> tint_symbol;
+};
+
+void compute_main_inner(uint tint_local_index, tint_module_vars_struct tint_module_vars) {
+  {
+    uint v = 0u;
+    v = tint_local_index;
+    while(true) {
+      uint const v_1 = v;
+      if ((v_1 >= 6u)) {
+        break;
+      }
+      atomic_store_explicit((&(*tint_module_vars.wg)[(v_1 / 2u)][(v_1 % 2u)][0u]), 0u, memory_order_relaxed);
+      {
+        v = (v_1 + 1u);
+      }
+      continue;
+    }
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomic_store_explicit((&(*tint_module_vars.wg)[2][1][0]), 1u, memory_order_relaxed);
+}
+kernel void compute_main(uint tint_local_index [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.wg=(&(*v_2).tint_symbol)};
+  compute_main_inner(tint_local_index, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomicStore/array/array.spvasm.expected.ir.msl b/test/tint/builtins/atomicStore/array/array.spvasm.expected.ir.msl
index 92c0fdd..03d4100 100644
--- a/test/tint/builtins/atomicStore/array/array.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomicStore/array/array.spvasm.expected.ir.msl
@@ -1,9 +1,70 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+template<typename T, size_t N>
+struct tint_array {
+  const constant T& operator[](size_t i) const constant { return elements[i]; }
+  device T& operator[](size_t i) device { return elements[i]; }
+  const device T& operator[](size_t i) const device { return elements[i]; }
+  thread T& operator[](size_t i) thread { return elements[i]; }
+  const thread T& operator[](size_t i) const thread { return elements[i]; }
+  threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+  const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+  T elements[N];
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicStore
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup tint_array<atomic_uint, 4>* wg;
+};
+struct tint_symbol_1 {
+  tint_array<atomic_uint, 4> tint_symbol;
+};
+
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  uint idx = 0u;
+  idx = local_invocation_index_2;
+  {
+    while(true) {
+      if (!((idx < 4u))) {
+        break;
+      }
+      uint const x_26 = idx;
+      atomic_store_explicit((&(*tint_module_vars.wg)[x_26]), 0u, memory_order_relaxed);
+      {
+        idx = (idx + 1u);
+      }
+      continue;
+    }
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomic_store_explicit((&(*tint_module_vars.wg)[1]), 1u, memory_order_relaxed);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_47 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_47, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  {
+    uint v = 0u;
+    v = local_invocation_index_1_param;
+    while(true) {
+      uint const v_1 = v;
+      if ((v_1 >= 4u)) {
+        break;
+      }
+      atomic_store_explicit((&(*tint_module_vars.wg)[v_1]), 0u, memory_order_relaxed);
+      {
+        v = (v_1 + 1u);
+      }
+      continue;
+    }
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .wg=(&(*v_2).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomicStore/array/array.wgsl.expected.ir.msl b/test/tint/builtins/atomicStore/array/array.wgsl.expected.ir.msl
index 3fa6a4b..356d798 100644
--- a/test/tint/builtins/atomicStore/array/array.wgsl.expected.ir.msl
+++ b/test/tint/builtins/atomicStore/array/array.wgsl.expected.ir.msl
@@ -1,9 +1,44 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+template<typename T, size_t N>
+struct tint_array {
+  const constant T& operator[](size_t i) const constant { return elements[i]; }
+  device T& operator[](size_t i) device { return elements[i]; }
+  const device T& operator[](size_t i) const device { return elements[i]; }
+  thread T& operator[](size_t i) thread { return elements[i]; }
+  const thread T& operator[](size_t i) const thread { return elements[i]; }
+  threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+  const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+  T elements[N];
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:388 internal compiler error: Switch() matched no cases. Type: tint::core::ir::BlockParam
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+struct tint_module_vars_struct {
+  threadgroup tint_array<atomic_uint, 4>* wg;
+};
+struct tint_symbol_1 {
+  tint_array<atomic_uint, 4> tint_symbol;
+};
+
+void compute_main_inner(uint tint_local_index, tint_module_vars_struct tint_module_vars) {
+  {
+    uint v = 0u;
+    v = tint_local_index;
+    while(true) {
+      uint const v_1 = v;
+      if ((v_1 >= 4u)) {
+        break;
+      }
+      atomic_store_explicit((&(*tint_module_vars.wg)[v_1]), 0u, memory_order_relaxed);
+      {
+        v = (v_1 + 1u);
+      }
+      continue;
+    }
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomic_store_explicit((&(*tint_module_vars.wg)[1]), 1u, memory_order_relaxed);
+}
+kernel void compute_main(uint tint_local_index [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.wg=(&(*v_2).tint_symbol)};
+  compute_main_inner(tint_local_index, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.ir.msl b/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.ir.msl
index 92c0fdd..7a49714 100644
--- a/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.ir.msl
@@ -1,9 +1,81 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+template<typename T, size_t N>
+struct tint_array {
+  const constant T& operator[](size_t i) const constant { return elements[i]; }
+  device T& operator[](size_t i) device { return elements[i]; }
+  const device T& operator[](size_t i) const device { return elements[i]; }
+  thread T& operator[](size_t i) thread { return elements[i]; }
+  const thread T& operator[](size_t i) const thread { return elements[i]; }
+  threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+  const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+  T elements[N];
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicStore
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* wg;
+};
+struct tint_symbol_1 {
+  tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3> tint_symbol;
+};
+
+uint tint_mod_u32(uint lhs, uint rhs) {
+  uint const v = select(rhs, 1u, (rhs == 0u));
+  return (lhs - ((lhs / v) * v));
+}
+uint tint_div_u32(uint lhs, uint rhs) {
+  return (lhs / select(rhs, 1u, (rhs == 0u)));
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  uint idx = 0u;
+  idx = local_invocation_index_2;
+  {
+    while(true) {
+      if (!((idx < 6u))) {
+        break;
+      }
+      uint const x_31 = idx;
+      uint const x_33 = idx;
+      uint const x_35 = idx;
+      uint const v_1 = tint_div_u32(x_31, 2u);
+      uint const v_2 = tint_mod_u32(x_33, 2u);
+      atomic_store_explicit((&(*tint_module_vars.wg)[v_1][v_2][tint_mod_u32(x_35, 1u)]), 0u, memory_order_relaxed);
+      {
+        idx = (idx + 1u);
+      }
+      continue;
+    }
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomic_store_explicit((&(*tint_module_vars.wg)[2][1][0]), 1u, memory_order_relaxed);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_57 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_57, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  {
+    uint v_3 = 0u;
+    v_3 = local_invocation_index_1_param;
+    while(true) {
+      uint const v_4 = v_3;
+      if ((v_4 >= 6u)) {
+        break;
+      }
+      atomic_store_explicit((&(*tint_module_vars.wg)[(v_4 / 2u)][(v_4 % 2u)][0u]), 0u, memory_order_relaxed);
+      {
+        v_3 = (v_4 + 1u);
+      }
+      continue;
+    }
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v_5 [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .wg=(&(*v_5).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.ir.msl b/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.ir.msl
index 3fa6a4b..298f1ab 100644
--- a/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.ir.msl
+++ b/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.ir.msl
@@ -1,9 +1,44 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+template<typename T, size_t N>
+struct tint_array {
+  const constant T& operator[](size_t i) const constant { return elements[i]; }
+  device T& operator[](size_t i) device { return elements[i]; }
+  const device T& operator[](size_t i) const device { return elements[i]; }
+  thread T& operator[](size_t i) thread { return elements[i]; }
+  const thread T& operator[](size_t i) const thread { return elements[i]; }
+  threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+  const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+  T elements[N];
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:388 internal compiler error: Switch() matched no cases. Type: tint::core::ir::BlockParam
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+struct tint_module_vars_struct {
+  threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* wg;
+};
+struct tint_symbol_1 {
+  tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3> tint_symbol;
+};
+
+void compute_main_inner(uint tint_local_index, tint_module_vars_struct tint_module_vars) {
+  {
+    uint v = 0u;
+    v = tint_local_index;
+    while(true) {
+      uint const v_1 = v;
+      if ((v_1 >= 6u)) {
+        break;
+      }
+      atomic_store_explicit((&(*tint_module_vars.wg)[(v_1 / 2u)][(v_1 % 2u)][0u]), 0u, memory_order_relaxed);
+      {
+        v = (v_1 + 1u);
+      }
+      continue;
+    }
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomic_store_explicit((&(*tint_module_vars.wg)[2][1][0]), 1u, memory_order_relaxed);
+}
+kernel void compute_main(uint tint_local_index [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.wg=(&(*v_2).tint_symbol)};
+  compute_main_inner(tint_local_index, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.ir.msl b/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.ir.msl
index 92c0fdd..abcbbc4 100644
--- a/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.ir.msl
@@ -1,9 +1,79 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+template<typename T, size_t N>
+struct tint_array {
+  const constant T& operator[](size_t i) const constant { return elements[i]; }
+  device T& operator[](size_t i) device { return elements[i]; }
+  const device T& operator[](size_t i) const device { return elements[i]; }
+  thread T& operator[](size_t i) thread { return elements[i]; }
+  const thread T& operator[](size_t i) const thread { return elements[i]; }
+  threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+  const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+  T elements[N];
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicStore
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+struct S_atomic {
+  int x;
+  atomic_uint a;
+  uint y;
+};
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup tint_array<S_atomic, 10>* wg;
+};
+struct tint_symbol_1 {
+  tint_array<S_atomic, 10> tint_symbol;
+};
+
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  uint idx = 0u;
+  idx = local_invocation_index_2;
+  {
+    while(true) {
+      if (!((idx < 10u))) {
+        break;
+      }
+      uint const x_28 = idx;
+      (*tint_module_vars.wg)[x_28].x = 0;
+      atomic_store_explicit((&(*tint_module_vars.wg)[x_28].a), 0u, memory_order_relaxed);
+      (*tint_module_vars.wg)[x_28].y = 0u;
+      {
+        idx = (idx + 1u);
+      }
+      continue;
+    }
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomic_store_explicit((&(*tint_module_vars.wg)[4].a), 1u, memory_order_relaxed);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_53 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_53, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  {
+    uint v = 0u;
+    v = local_invocation_index_1_param;
+    while(true) {
+      uint const v_1 = v;
+      if ((v_1 >= 10u)) {
+        break;
+      }
+      (*tint_module_vars.wg)[v_1].x = 0;
+      atomic_store_explicit((&(*tint_module_vars.wg)[v_1].a), 0u, memory_order_relaxed);
+      (*tint_module_vars.wg)[v_1].y = 0u;
+      {
+        v = (v_1 + 1u);
+      }
+      continue;
+    }
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .wg=(&(*v_2).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.ir.msl b/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.ir.msl
index 3fa6a4b..e585264 100644
--- a/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.ir.msl
+++ b/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.ir.msl
@@ -1,9 +1,51 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+template<typename T, size_t N>
+struct tint_array {
+  const constant T& operator[](size_t i) const constant { return elements[i]; }
+  device T& operator[](size_t i) device { return elements[i]; }
+  const device T& operator[](size_t i) const device { return elements[i]; }
+  thread T& operator[](size_t i) thread { return elements[i]; }
+  const thread T& operator[](size_t i) const thread { return elements[i]; }
+  threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+  const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+  T elements[N];
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:388 internal compiler error: Switch() matched no cases. Type: tint::core::ir::BlockParam
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+struct S {
+  int x;
+  atomic_uint a;
+  uint y;
+};
+struct tint_module_vars_struct {
+  threadgroup tint_array<S, 10>* wg;
+};
+struct tint_symbol_1 {
+  tint_array<S, 10> tint_symbol;
+};
+
+void compute_main_inner(uint tint_local_index, tint_module_vars_struct tint_module_vars) {
+  {
+    uint v = 0u;
+    v = tint_local_index;
+    while(true) {
+      uint const v_1 = v;
+      if ((v_1 >= 10u)) {
+        break;
+      }
+      (*tint_module_vars.wg)[v_1].x = 0;
+      atomic_store_explicit((&(*tint_module_vars.wg)[v_1].a), 0u, memory_order_relaxed);
+      (*tint_module_vars.wg)[v_1].y = 0u;
+      {
+        v = (v_1 + 1u);
+      }
+      continue;
+    }
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomic_store_explicit((&(*tint_module_vars.wg)[4].a), 1u, memory_order_relaxed);
+}
+kernel void compute_main(uint tint_local_index [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.wg=(&(*v_2).tint_symbol)};
+  compute_main_inner(tint_local_index, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomicStore/struct/flat_multiple_atomics.spvasm.expected.ir.msl b/test/tint/builtins/atomicStore/struct/flat_multiple_atomics.spvasm.expected.ir.msl
index 92c0fdd..5c1e7e9 100644
--- a/test/tint/builtins/atomicStore/struct/flat_multiple_atomics.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomicStore/struct/flat_multiple_atomics.spvasm.expected.ir.msl
@@ -1,9 +1,42 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct S_atomic {
+  int x;
+  atomic_uint a;
+  atomic_uint b;
+};
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup S_atomic* wg;
+};
+struct tint_symbol_1 {
+  S_atomic tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicStore
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  (*tint_module_vars.wg).x = 0;
+  atomic_store_explicit((&(*tint_module_vars.wg).a), 0u, memory_order_relaxed);
+  atomic_store_explicit((&(*tint_module_vars.wg).b), 0u, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomic_store_explicit((&(*tint_module_vars.wg).a), 1u, memory_order_relaxed);
+  atomic_store_explicit((&(*tint_module_vars.wg).b), 2u, memory_order_relaxed);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_39 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_39, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    (*tint_module_vars.wg).x = 0;
+    atomic_store_explicit((&(*tint_module_vars.wg).a), 0u, memory_order_relaxed);
+    atomic_store_explicit((&(*tint_module_vars.wg).b), 0u, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .wg=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomicStore/struct/flat_multiple_atomics.wgsl.expected.ir.msl b/test/tint/builtins/atomicStore/struct/flat_multiple_atomics.wgsl.expected.ir.msl
index 92c0fdd..764fae1 100644
--- a/test/tint/builtins/atomicStore/struct/flat_multiple_atomics.wgsl.expected.ir.msl
+++ b/test/tint/builtins/atomicStore/struct/flat_multiple_atomics.wgsl.expected.ir.msl
@@ -1,9 +1,28 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct S {
+  int x;
+  atomic_uint a;
+  atomic_uint b;
+};
+struct tint_module_vars_struct {
+  threadgroup S* wg;
+};
+struct tint_symbol_1 {
+  S tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicStore
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void compute_main_inner(uint tint_local_index, tint_module_vars_struct tint_module_vars) {
+  if ((tint_local_index == 0u)) {
+    (*tint_module_vars.wg).x = 0;
+    atomic_store_explicit((&(*tint_module_vars.wg).a), 0u, memory_order_relaxed);
+    atomic_store_explicit((&(*tint_module_vars.wg).b), 0u, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomic_store_explicit((&(*tint_module_vars.wg).a), 1u, memory_order_relaxed);
+  atomic_store_explicit((&(*tint_module_vars.wg).b), 2u, memory_order_relaxed);
+}
+kernel void compute_main(uint tint_local_index [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.wg=(&(*v).tint_symbol)};
+  compute_main_inner(tint_local_index, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomicStore/struct/flat_single_atomic.spvasm.expected.ir.msl b/test/tint/builtins/atomicStore/struct/flat_single_atomic.spvasm.expected.ir.msl
index 92c0fdd..269c19e 100644
--- a/test/tint/builtins/atomicStore/struct/flat_single_atomic.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomicStore/struct/flat_single_atomic.spvasm.expected.ir.msl
@@ -1,9 +1,41 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct S_atomic {
+  int x;
+  atomic_uint a;
+  uint y;
+};
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup S_atomic* wg;
+};
+struct tint_symbol_1 {
+  S_atomic tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicStore
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  (*tint_module_vars.wg).x = 0;
+  atomic_store_explicit((&(*tint_module_vars.wg).a), 0u, memory_order_relaxed);
+  (*tint_module_vars.wg).y = 0u;
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomic_store_explicit((&(*tint_module_vars.wg).a), 1u, memory_order_relaxed);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_35 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_35, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    (*tint_module_vars.wg).x = 0;
+    atomic_store_explicit((&(*tint_module_vars.wg).a), 0u, memory_order_relaxed);
+    (*tint_module_vars.wg).y = 0u;
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .wg=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomicStore/struct/flat_single_atomic.wgsl.expected.ir.msl b/test/tint/builtins/atomicStore/struct/flat_single_atomic.wgsl.expected.ir.msl
index 92c0fdd..5a8c8fb 100644
--- a/test/tint/builtins/atomicStore/struct/flat_single_atomic.wgsl.expected.ir.msl
+++ b/test/tint/builtins/atomicStore/struct/flat_single_atomic.wgsl.expected.ir.msl
@@ -1,9 +1,27 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct S {
+  int x;
+  atomic_uint a;
+  uint y;
+};
+struct tint_module_vars_struct {
+  threadgroup S* wg;
+};
+struct tint_symbol_1 {
+  S tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicStore
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void compute_main_inner(uint tint_local_index, tint_module_vars_struct tint_module_vars) {
+  if ((tint_local_index == 0u)) {
+    (*tint_module_vars.wg).x = 0;
+    atomic_store_explicit((&(*tint_module_vars.wg).a), 0u, memory_order_relaxed);
+    (*tint_module_vars.wg).y = 0u;
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomic_store_explicit((&(*tint_module_vars.wg).a), 1u, memory_order_relaxed);
+}
+kernel void compute_main(uint tint_local_index [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.wg=(&(*v).tint_symbol)};
+  compute_main_inner(tint_local_index, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomicStore/struct/nested.spvasm.expected.ir.msl b/test/tint/builtins/atomicStore/struct/nested.spvasm.expected.ir.msl
index 92c0fdd..f1ad938 100644
--- a/test/tint/builtins/atomicStore/struct/nested.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomicStore/struct/nested.spvasm.expected.ir.msl
@@ -1,9 +1,68 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct S0_atomic {
+  int x;
+  atomic_uint a;
+  int y;
+  int z;
+};
+struct S1_atomic {
+  int x;
+  S0_atomic a;
+  int y;
+  int z;
+};
+struct S2_atomic {
+  int x;
+  int y;
+  int z;
+  S1_atomic a;
+};
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup S2_atomic* wg;
+};
+struct tint_symbol_1 {
+  S2_atomic tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicStore
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  (*tint_module_vars.wg).x = 0;
+  (*tint_module_vars.wg).y = 0;
+  (*tint_module_vars.wg).z = 0;
+  (*tint_module_vars.wg).a.x = 0;
+  (*tint_module_vars.wg).a.a.x = 0;
+  atomic_store_explicit((&(*tint_module_vars.wg).a.a.a), 0u, memory_order_relaxed);
+  (*tint_module_vars.wg).a.a.y = 0;
+  (*tint_module_vars.wg).a.a.z = 0;
+  (*tint_module_vars.wg).a.y = 0;
+  (*tint_module_vars.wg).a.z = 0;
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomic_store_explicit((&(*tint_module_vars.wg).a.a.a), 1u, memory_order_relaxed);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_44 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_44, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    (*tint_module_vars.wg).x = 0;
+    (*tint_module_vars.wg).y = 0;
+    (*tint_module_vars.wg).z = 0;
+    (*tint_module_vars.wg).a.x = 0;
+    (*tint_module_vars.wg).a.a.x = 0;
+    atomic_store_explicit((&(*tint_module_vars.wg).a.a.a), 0u, memory_order_relaxed);
+    (*tint_module_vars.wg).a.a.y = 0;
+    (*tint_module_vars.wg).a.a.z = 0;
+    (*tint_module_vars.wg).a.y = 0;
+    (*tint_module_vars.wg).a.z = 0;
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .wg=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomicStore/struct/nested.wgsl.expected.ir.msl b/test/tint/builtins/atomicStore/struct/nested.wgsl.expected.ir.msl
index 92c0fdd..04b3b7f 100644
--- a/test/tint/builtins/atomicStore/struct/nested.wgsl.expected.ir.msl
+++ b/test/tint/builtins/atomicStore/struct/nested.wgsl.expected.ir.msl
@@ -1,9 +1,47 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct S0 {
+  int x;
+  atomic_uint a;
+  int y;
+  int z;
+};
+struct S1 {
+  int x;
+  S0 a;
+  int y;
+  int z;
+};
+struct S2 {
+  int x;
+  int y;
+  int z;
+  S1 a;
+};
+struct tint_module_vars_struct {
+  threadgroup S2* wg;
+};
+struct tint_symbol_1 {
+  S2 tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicStore
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void compute_main_inner(uint tint_local_index, tint_module_vars_struct tint_module_vars) {
+  if ((tint_local_index == 0u)) {
+    (*tint_module_vars.wg).x = 0;
+    (*tint_module_vars.wg).y = 0;
+    (*tint_module_vars.wg).z = 0;
+    (*tint_module_vars.wg).a.x = 0;
+    (*tint_module_vars.wg).a.a.x = 0;
+    atomic_store_explicit((&(*tint_module_vars.wg).a.a.a), 0u, memory_order_relaxed);
+    (*tint_module_vars.wg).a.a.y = 0;
+    (*tint_module_vars.wg).a.a.z = 0;
+    (*tint_module_vars.wg).a.y = 0;
+    (*tint_module_vars.wg).a.z = 0;
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomic_store_explicit((&(*tint_module_vars.wg).a.a.a), 1u, memory_order_relaxed);
+}
+kernel void compute_main(uint tint_local_index [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.wg=(&(*v).tint_symbol)};
+  compute_main_inner(tint_local_index, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.ir.msl b/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.ir.msl
index 92c0fdd..d40c886 100644
--- a/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.ir.msl
@@ -1,9 +1,81 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+template<typename T, size_t N>
+struct tint_array {
+  const constant T& operator[](size_t i) const constant { return elements[i]; }
+  device T& operator[](size_t i) device { return elements[i]; }
+  const device T& operator[](size_t i) const device { return elements[i]; }
+  thread T& operator[](size_t i) thread { return elements[i]; }
+  const thread T& operator[](size_t i) const thread { return elements[i]; }
+  threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+  const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+  T elements[N];
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicStore
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+struct S_atomic {
+  int x;
+  tint_array<atomic_uint, 10> a;
+  uint y;
+};
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup S_atomic* wg;
+};
+struct tint_symbol_1 {
+  S_atomic tint_symbol;
+};
+
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  uint idx = 0u;
+  (*tint_module_vars.wg).x = 0;
+  (*tint_module_vars.wg).y = 0u;
+  idx = local_invocation_index_2;
+  {
+    while(true) {
+      if (!((idx < 10u))) {
+        break;
+      }
+      uint const x_35 = idx;
+      atomic_store_explicit((&(*tint_module_vars.wg).a[x_35]), 0u, memory_order_relaxed);
+      {
+        idx = (idx + 1u);
+      }
+      continue;
+    }
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomic_store_explicit((&(*tint_module_vars.wg).a[4]), 1u, memory_order_relaxed);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_53 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_53, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    (*tint_module_vars.wg).x = 0;
+    (*tint_module_vars.wg).y = 0u;
+  }
+  {
+    uint v = 0u;
+    v = local_invocation_index_1_param;
+    while(true) {
+      uint const v_1 = v;
+      if ((v_1 >= 10u)) {
+        break;
+      }
+      atomic_store_explicit((&(*tint_module_vars.wg).a[v_1]), 0u, memory_order_relaxed);
+      {
+        v = (v_1 + 1u);
+      }
+      continue;
+    }
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .wg=(&(*v_2).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.ir.msl b/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.ir.msl
index 3fa6a4b..ff885f5 100644
--- a/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.ir.msl
+++ b/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.ir.msl
@@ -1,9 +1,53 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+template<typename T, size_t N>
+struct tint_array {
+  const constant T& operator[](size_t i) const constant { return elements[i]; }
+  device T& operator[](size_t i) device { return elements[i]; }
+  const device T& operator[](size_t i) const device { return elements[i]; }
+  thread T& operator[](size_t i) thread { return elements[i]; }
+  const thread T& operator[](size_t i) const thread { return elements[i]; }
+  threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
+  const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
+  T elements[N];
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:388 internal compiler error: Switch() matched no cases. Type: tint::core::ir::BlockParam
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+struct S {
+  int x;
+  tint_array<atomic_uint, 10> a;
+  uint y;
+};
+struct tint_module_vars_struct {
+  threadgroup S* wg;
+};
+struct tint_symbol_1 {
+  S tint_symbol;
+};
+
+void compute_main_inner(uint tint_local_index, tint_module_vars_struct tint_module_vars) {
+  if ((tint_local_index == 0u)) {
+    (*tint_module_vars.wg).x = 0;
+    (*tint_module_vars.wg).y = 0u;
+  }
+  {
+    uint v = 0u;
+    v = tint_local_index;
+    while(true) {
+      uint const v_1 = v;
+      if ((v_1 >= 10u)) {
+        break;
+      }
+      atomic_store_explicit((&(*tint_module_vars.wg).a[v_1]), 0u, memory_order_relaxed);
+      {
+        v = (v_1 + 1u);
+      }
+      continue;
+    }
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomic_store_explicit((&(*tint_module_vars.wg).a[4]), 1u, memory_order_relaxed);
+}
+kernel void compute_main(uint tint_local_index [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.wg=(&(*v_2).tint_symbol)};
+  compute_main_inner(tint_local_index, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomicStore/struct/via_ptr_let.spvasm.expected.ir.msl b/test/tint/builtins/atomicStore/struct/via_ptr_let.spvasm.expected.ir.msl
index 92c0fdd..269c19e 100644
--- a/test/tint/builtins/atomicStore/struct/via_ptr_let.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomicStore/struct/via_ptr_let.spvasm.expected.ir.msl
@@ -1,9 +1,41 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct S_atomic {
+  int x;
+  atomic_uint a;
+  uint y;
+};
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup S_atomic* wg;
+};
+struct tint_symbol_1 {
+  S_atomic tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicStore
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  (*tint_module_vars.wg).x = 0;
+  atomic_store_explicit((&(*tint_module_vars.wg).a), 0u, memory_order_relaxed);
+  (*tint_module_vars.wg).y = 0u;
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomic_store_explicit((&(*tint_module_vars.wg).a), 1u, memory_order_relaxed);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_35 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_35, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    (*tint_module_vars.wg).x = 0;
+    atomic_store_explicit((&(*tint_module_vars.wg).a), 0u, memory_order_relaxed);
+    (*tint_module_vars.wg).y = 0u;
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .wg=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomicStore/struct/via_ptr_let.wgsl.expected.ir.msl b/test/tint/builtins/atomicStore/struct/via_ptr_let.wgsl.expected.ir.msl
index 92c0fdd..d1d4a74 100644
--- a/test/tint/builtins/atomicStore/struct/via_ptr_let.wgsl.expected.ir.msl
+++ b/test/tint/builtins/atomicStore/struct/via_ptr_let.wgsl.expected.ir.msl
@@ -1,9 +1,29 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct S {
+  int x;
+  atomic_uint a;
+  uint y;
+};
+struct tint_module_vars_struct {
+  threadgroup S* wg;
+};
+struct tint_symbol_1 {
+  S tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicStore
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void compute_main_inner(uint tint_local_index, tint_module_vars_struct tint_module_vars) {
+  if ((tint_local_index == 0u)) {
+    (*tint_module_vars.wg).x = 0;
+    atomic_store_explicit((&(*tint_module_vars.wg).a), 0u, memory_order_relaxed);
+    (*tint_module_vars.wg).y = 0u;
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  threadgroup S* const p0 = tint_module_vars.wg;
+  threadgroup atomic_uint* const p1 = (&(*p0).a);
+  atomic_store_explicit(p1, 1u, memory_order_relaxed);
+}
+kernel void compute_main(uint tint_local_index [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.wg=(&(*v).tint_symbol)};
+  compute_main_inner(tint_local_index, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicAdd/storage_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicAdd/storage_i32.spvasm.expected.ir.msl
index 68658f0..0c74870 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicAdd/storage_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicAdd/storage_i32.spvasm.expected.ir.msl
@@ -1,52 +1,28 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_int arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<i32> @offset(0)
+void atomicAdd_d32fe4(tint_module_vars_struct tint_module_vars) {
+  int res = 0;
+  int const x_9 = atomic_fetch_add_explicit((&(*tint_module_vars.sb_rw).arg_0), 1, memory_order_relaxed);
+  res = x_9;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAdd_d32fe4(tint_module_vars);
 }
-
-%atomicAdd_d32fe4 = func():void {
-  $B2: {
-    %res:ptr<function, i32, read_write> = var, 0i
-    %4:ptr<storage, atomic<i32>, read_write> = access %sb_rw, 0u
-    %5:i32 = atomicAdd %4, 1i
-    %x_9:i32 = let %5
-    store %res, %x_9
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %8:void = call %atomicAdd_d32fe4
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAdd_d32fe4(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %10:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %12:void = call %atomicAdd_d32fe4
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %14:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicAdd/storage_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicAdd/storage_u32.spvasm.expected.ir.msl
index 1375ee3..f76e4d6 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicAdd/storage_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicAdd/storage_u32.spvasm.expected.ir.msl
@@ -1,52 +1,28 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_uint arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<u32> @offset(0)
+void atomicAdd_8a199a(tint_module_vars_struct tint_module_vars) {
+  uint res = 0u;
+  uint const x_9 = atomic_fetch_add_explicit((&(*tint_module_vars.sb_rw).arg_0), 1u, memory_order_relaxed);
+  res = x_9;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAdd_8a199a(tint_module_vars);
 }
-
-%atomicAdd_8a199a = func():void {
-  $B2: {
-    %res:ptr<function, u32, read_write> = var, 0u
-    %4:ptr<storage, atomic<u32>, read_write> = access %sb_rw, 0u
-    %5:u32 = atomicAdd %4, 1u
-    %x_9:u32 = let %5
-    store %res, %x_9
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %8:void = call %atomicAdd_8a199a
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAdd_8a199a(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %10:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %12:void = call %atomicAdd_8a199a
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %14:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicAdd/workgroup_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicAdd/workgroup_i32.spvasm.expected.ir.msl
index f7dc0d0..af1ce0c 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicAdd/workgroup_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicAdd/workgroup_i32.spvasm.expected.ir.msl
@@ -1,9 +1,37 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_int* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_int tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicAdd
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicAdd_794055(tint_module_vars_struct tint_module_vars) {
+  int res = 0;
+  int const x_11 = atomic_fetch_add_explicit(tint_module_vars.arg_0, 1, memory_order_relaxed);
+  res = x_11;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicAdd_794055(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_31 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_31, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicAdd/workgroup_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicAdd/workgroup_u32.spvasm.expected.ir.msl
index f7dc0d0..b826e33 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicAdd/workgroup_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicAdd/workgroup_u32.spvasm.expected.ir.msl
@@ -1,9 +1,37 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_uint* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_uint tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicAdd
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicAdd_d5db1d(tint_module_vars_struct tint_module_vars) {
+  uint res = 0u;
+  uint const x_10 = atomic_fetch_add_explicit(tint_module_vars.arg_0, 1u, memory_order_relaxed);
+  res = x_10;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicAdd_d5db1d(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_30 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_30, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicAnd/storage_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicAnd/storage_i32.spvasm.expected.ir.msl
index f636432..3c7e553e 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicAnd/storage_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicAnd/storage_i32.spvasm.expected.ir.msl
@@ -1,52 +1,28 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_int arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<i32> @offset(0)
+void atomicAnd_152966(tint_module_vars_struct tint_module_vars) {
+  int res = 0;
+  int const x_9 = atomic_fetch_and_explicit((&(*tint_module_vars.sb_rw).arg_0), 1, memory_order_relaxed);
+  res = x_9;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAnd_152966(tint_module_vars);
 }
-
-%atomicAnd_152966 = func():void {
-  $B2: {
-    %res:ptr<function, i32, read_write> = var, 0i
-    %4:ptr<storage, atomic<i32>, read_write> = access %sb_rw, 0u
-    %5:i32 = atomicAnd %4, 1i
-    %x_9:i32 = let %5
-    store %res, %x_9
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %8:void = call %atomicAnd_152966
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAnd_152966(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %10:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %12:void = call %atomicAnd_152966
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %14:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicAnd/storage_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicAnd/storage_u32.spvasm.expected.ir.msl
index dd4689a..5e4d29c 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicAnd/storage_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicAnd/storage_u32.spvasm.expected.ir.msl
@@ -1,52 +1,28 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_uint arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<u32> @offset(0)
+void atomicAnd_85a8d9(tint_module_vars_struct tint_module_vars) {
+  uint res = 0u;
+  uint const x_9 = atomic_fetch_and_explicit((&(*tint_module_vars.sb_rw).arg_0), 1u, memory_order_relaxed);
+  res = x_9;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAnd_85a8d9(tint_module_vars);
 }
-
-%atomicAnd_85a8d9 = func():void {
-  $B2: {
-    %res:ptr<function, u32, read_write> = var, 0u
-    %4:ptr<storage, atomic<u32>, read_write> = access %sb_rw, 0u
-    %5:u32 = atomicAnd %4, 1u
-    %x_9:u32 = let %5
-    store %res, %x_9
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %8:void = call %atomicAnd_85a8d9
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAnd_85a8d9(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %10:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %12:void = call %atomicAnd_85a8d9
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %14:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicAnd/workgroup_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicAnd/workgroup_i32.spvasm.expected.ir.msl
index cb4c94c..eda61ed 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicAnd/workgroup_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicAnd/workgroup_i32.spvasm.expected.ir.msl
@@ -1,9 +1,37 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_int* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_int tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicAnd
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicAnd_45a819(tint_module_vars_struct tint_module_vars) {
+  int res = 0;
+  int const x_11 = atomic_fetch_and_explicit(tint_module_vars.arg_0, 1, memory_order_relaxed);
+  res = x_11;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicAnd_45a819(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_31 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_31, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicAnd/workgroup_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicAnd/workgroup_u32.spvasm.expected.ir.msl
index cb4c94c..d12e98e 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicAnd/workgroup_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicAnd/workgroup_u32.spvasm.expected.ir.msl
@@ -1,9 +1,37 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_uint* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_uint tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicAnd
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicAnd_34edd3(tint_module_vars_struct tint_module_vars) {
+  uint res = 0u;
+  uint const x_10 = atomic_fetch_and_explicit(tint_module_vars.arg_0, 1u, memory_order_relaxed);
+  res = x_10;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicAnd_34edd3(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_30 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_30, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicExchange/storage_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicExchange/storage_i32.spvasm.expected.ir.msl
index 89fae49..efdc47a 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicExchange/storage_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicExchange/storage_i32.spvasm.expected.ir.msl
@@ -1,52 +1,28 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_int arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<i32> @offset(0)
+void atomicExchange_f2e22f(tint_module_vars_struct tint_module_vars) {
+  int res = 0;
+  int const x_9 = atomic_exchange_explicit((&(*tint_module_vars.sb_rw).arg_0), 1, memory_order_relaxed);
+  res = x_9;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicExchange_f2e22f(tint_module_vars);
 }
-
-%atomicExchange_f2e22f = func():void {
-  $B2: {
-    %res:ptr<function, i32, read_write> = var, 0i
-    %4:ptr<storage, atomic<i32>, read_write> = access %sb_rw, 0u
-    %5:i32 = atomicExchange %4, 1i
-    %x_9:i32 = let %5
-    store %res, %x_9
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %8:void = call %atomicExchange_f2e22f
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicExchange_f2e22f(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %10:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %12:void = call %atomicExchange_f2e22f
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %14:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicExchange/storage_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicExchange/storage_u32.spvasm.expected.ir.msl
index 6eb9ff0..e9d98ad 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicExchange/storage_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicExchange/storage_u32.spvasm.expected.ir.msl
@@ -1,52 +1,28 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_uint arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<u32> @offset(0)
+void atomicExchange_d59712(tint_module_vars_struct tint_module_vars) {
+  uint res = 0u;
+  uint const x_9 = atomic_exchange_explicit((&(*tint_module_vars.sb_rw).arg_0), 1u, memory_order_relaxed);
+  res = x_9;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicExchange_d59712(tint_module_vars);
 }
-
-%atomicExchange_d59712 = func():void {
-  $B2: {
-    %res:ptr<function, u32, read_write> = var, 0u
-    %4:ptr<storage, atomic<u32>, read_write> = access %sb_rw, 0u
-    %5:u32 = atomicExchange %4, 1u
-    %x_9:u32 = let %5
-    store %res, %x_9
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %8:void = call %atomicExchange_d59712
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicExchange_d59712(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %10:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %12:void = call %atomicExchange_d59712
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %14:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicExchange/workgroup_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicExchange/workgroup_i32.spvasm.expected.ir.msl
index 2f8d44e..8001277 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicExchange/workgroup_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicExchange/workgroup_i32.spvasm.expected.ir.msl
@@ -1,9 +1,37 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_int* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_int tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicExchange
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicExchange_e114ba(tint_module_vars_struct tint_module_vars) {
+  int res = 0;
+  int const x_11 = atomic_exchange_explicit(tint_module_vars.arg_0, 1, memory_order_relaxed);
+  res = x_11;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicExchange_e114ba(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_31 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_31, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicExchange/workgroup_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicExchange/workgroup_u32.spvasm.expected.ir.msl
index 2f8d44e..f5a0409 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicExchange/workgroup_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicExchange/workgroup_u32.spvasm.expected.ir.msl
@@ -1,9 +1,37 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_uint* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_uint tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicExchange
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicExchange_0a5dca(tint_module_vars_struct tint_module_vars) {
+  uint res = 0u;
+  uint const x_10 = atomic_exchange_explicit(tint_module_vars.arg_0, 1u, memory_order_relaxed);
+  res = x_10;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicExchange_0a5dca(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_30 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_30, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicLoad/storage_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicLoad/storage_i32.spvasm.expected.ir.msl
index 7b20853..18eb9c8 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicLoad/storage_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicLoad/storage_i32.spvasm.expected.ir.msl
@@ -1,52 +1,28 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_int arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<i32> @offset(0)
+void atomicLoad_0806ad(tint_module_vars_struct tint_module_vars) {
+  int res = 0;
+  int const x_9 = atomic_load_explicit((&(*tint_module_vars.sb_rw).arg_0), memory_order_relaxed);
+  res = x_9;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicLoad_0806ad(tint_module_vars);
 }
-
-%atomicLoad_0806ad = func():void {
-  $B2: {
-    %res:ptr<function, i32, read_write> = var, 0i
-    %4:ptr<storage, atomic<i32>, read_write> = access %sb_rw, 0u
-    %5:i32 = atomicLoad %4
-    %x_9:i32 = let %5
-    store %res, %x_9
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %8:void = call %atomicLoad_0806ad
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicLoad_0806ad(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %10:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %12:void = call %atomicLoad_0806ad
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %14:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicLoad/storage_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicLoad/storage_u32.spvasm.expected.ir.msl
index 3c25b76..da2266a 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicLoad/storage_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicLoad/storage_u32.spvasm.expected.ir.msl
@@ -1,52 +1,28 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_uint arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<u32> @offset(0)
+void atomicLoad_fe6cc3(tint_module_vars_struct tint_module_vars) {
+  uint res = 0u;
+  uint const x_9 = atomic_load_explicit((&(*tint_module_vars.sb_rw).arg_0), memory_order_relaxed);
+  res = x_9;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicLoad_fe6cc3(tint_module_vars);
 }
-
-%atomicLoad_fe6cc3 = func():void {
-  $B2: {
-    %res:ptr<function, u32, read_write> = var, 0u
-    %4:ptr<storage, atomic<u32>, read_write> = access %sb_rw, 0u
-    %5:u32 = atomicLoad %4
-    %x_9:u32 = let %5
-    store %res, %x_9
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %8:void = call %atomicLoad_fe6cc3
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicLoad_fe6cc3(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %10:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %12:void = call %atomicLoad_fe6cc3
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %14:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicLoad/workgroup_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicLoad/workgroup_i32.spvasm.expected.ir.msl
index e62fe24..4f2c6fb 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicLoad/workgroup_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicLoad/workgroup_i32.spvasm.expected.ir.msl
@@ -1,9 +1,37 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_int* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_int tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicLoad
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicLoad_afcc03(tint_module_vars_struct tint_module_vars) {
+  int res = 0;
+  int const x_11 = atomic_load_explicit(tint_module_vars.arg_0, memory_order_relaxed);
+  res = x_11;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicLoad_afcc03(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_30 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_30, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicLoad/workgroup_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicLoad/workgroup_u32.spvasm.expected.ir.msl
index e62fe24..6dc06c4 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicLoad/workgroup_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicLoad/workgroup_u32.spvasm.expected.ir.msl
@@ -1,9 +1,37 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_uint* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_uint tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicLoad
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicLoad_361bf1(tint_module_vars_struct tint_module_vars) {
+  uint res = 0u;
+  uint const x_10 = atomic_load_explicit(tint_module_vars.arg_0, memory_order_relaxed);
+  res = x_10;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicLoad_361bf1(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_29 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_29, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicMax/storage_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicMax/storage_i32.spvasm.expected.ir.msl
index e8fca07..cf34a49 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicMax/storage_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicMax/storage_i32.spvasm.expected.ir.msl
@@ -1,52 +1,28 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_int arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<i32> @offset(0)
+void atomicMax_92aa72(tint_module_vars_struct tint_module_vars) {
+  int res = 0;
+  int const x_9 = atomic_fetch_max_explicit((&(*tint_module_vars.sb_rw).arg_0), 1, memory_order_relaxed);
+  res = x_9;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicMax_92aa72(tint_module_vars);
 }
-
-%atomicMax_92aa72 = func():void {
-  $B2: {
-    %res:ptr<function, i32, read_write> = var, 0i
-    %4:ptr<storage, atomic<i32>, read_write> = access %sb_rw, 0u
-    %5:i32 = atomicMax %4, 1i
-    %x_9:i32 = let %5
-    store %res, %x_9
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %8:void = call %atomicMax_92aa72
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicMax_92aa72(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %10:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %12:void = call %atomicMax_92aa72
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %14:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicMax/storage_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicMax/storage_u32.spvasm.expected.ir.msl
index 4433c19..0b65b1a 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicMax/storage_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicMax/storage_u32.spvasm.expected.ir.msl
@@ -1,52 +1,28 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_uint arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<u32> @offset(0)
+void atomicMax_51b9be(tint_module_vars_struct tint_module_vars) {
+  uint res = 0u;
+  uint const x_9 = atomic_fetch_max_explicit((&(*tint_module_vars.sb_rw).arg_0), 1u, memory_order_relaxed);
+  res = x_9;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicMax_51b9be(tint_module_vars);
 }
-
-%atomicMax_51b9be = func():void {
-  $B2: {
-    %res:ptr<function, u32, read_write> = var, 0u
-    %4:ptr<storage, atomic<u32>, read_write> = access %sb_rw, 0u
-    %5:u32 = atomicMax %4, 1u
-    %x_9:u32 = let %5
-    store %res, %x_9
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %8:void = call %atomicMax_51b9be
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicMax_51b9be(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %10:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %12:void = call %atomicMax_51b9be
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %14:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicMax/workgroup_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicMax/workgroup_i32.spvasm.expected.ir.msl
index 6687606..66aed9a 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicMax/workgroup_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicMax/workgroup_i32.spvasm.expected.ir.msl
@@ -1,9 +1,37 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_int* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_int tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicMax
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicMax_a89cc3(tint_module_vars_struct tint_module_vars) {
+  int res = 0;
+  int const x_11 = atomic_fetch_max_explicit(tint_module_vars.arg_0, 1, memory_order_relaxed);
+  res = x_11;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicMax_a89cc3(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_31 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_31, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicMax/workgroup_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicMax/workgroup_u32.spvasm.expected.ir.msl
index 6687606..17cc307 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicMax/workgroup_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicMax/workgroup_u32.spvasm.expected.ir.msl
@@ -1,9 +1,37 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_uint* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_uint tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicMax
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicMax_beccfc(tint_module_vars_struct tint_module_vars) {
+  uint res = 0u;
+  uint const x_10 = atomic_fetch_max_explicit(tint_module_vars.arg_0, 1u, memory_order_relaxed);
+  res = x_10;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicMax_beccfc(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_30 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_30, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicMin/storage_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicMin/storage_i32.spvasm.expected.ir.msl
index 21e0d7d..b2141b0 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicMin/storage_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicMin/storage_i32.spvasm.expected.ir.msl
@@ -1,52 +1,28 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_int arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<i32> @offset(0)
+void atomicMin_8e38dc(tint_module_vars_struct tint_module_vars) {
+  int res = 0;
+  int const x_9 = atomic_fetch_min_explicit((&(*tint_module_vars.sb_rw).arg_0), 1, memory_order_relaxed);
+  res = x_9;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicMin_8e38dc(tint_module_vars);
 }
-
-%atomicMin_8e38dc = func():void {
-  $B2: {
-    %res:ptr<function, i32, read_write> = var, 0i
-    %4:ptr<storage, atomic<i32>, read_write> = access %sb_rw, 0u
-    %5:i32 = atomicMin %4, 1i
-    %x_9:i32 = let %5
-    store %res, %x_9
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %8:void = call %atomicMin_8e38dc
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicMin_8e38dc(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %10:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %12:void = call %atomicMin_8e38dc
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %14:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicMin/storage_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicMin/storage_u32.spvasm.expected.ir.msl
index d099c9f..b2bb686 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicMin/storage_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicMin/storage_u32.spvasm.expected.ir.msl
@@ -1,52 +1,28 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_uint arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<u32> @offset(0)
+void atomicMin_c67a74(tint_module_vars_struct tint_module_vars) {
+  uint res = 0u;
+  uint const x_9 = atomic_fetch_min_explicit((&(*tint_module_vars.sb_rw).arg_0), 1u, memory_order_relaxed);
+  res = x_9;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicMin_c67a74(tint_module_vars);
 }
-
-%atomicMin_c67a74 = func():void {
-  $B2: {
-    %res:ptr<function, u32, read_write> = var, 0u
-    %4:ptr<storage, atomic<u32>, read_write> = access %sb_rw, 0u
-    %5:u32 = atomicMin %4, 1u
-    %x_9:u32 = let %5
-    store %res, %x_9
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %8:void = call %atomicMin_c67a74
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicMin_c67a74(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %10:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %12:void = call %atomicMin_c67a74
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %14:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicMin/workgroup_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicMin/workgroup_i32.spvasm.expected.ir.msl
index 829342e..ae90582 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicMin/workgroup_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicMin/workgroup_i32.spvasm.expected.ir.msl
@@ -1,9 +1,37 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_int* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_int tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicMin
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicMin_278235(tint_module_vars_struct tint_module_vars) {
+  int res = 0;
+  int const x_11 = atomic_fetch_min_explicit(tint_module_vars.arg_0, 1, memory_order_relaxed);
+  res = x_11;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicMin_278235(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_31 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_31, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicMin/workgroup_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicMin/workgroup_u32.spvasm.expected.ir.msl
index 829342e..3b706a2 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicMin/workgroup_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicMin/workgroup_u32.spvasm.expected.ir.msl
@@ -1,9 +1,37 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_uint* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_uint tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicMin
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicMin_69d383(tint_module_vars_struct tint_module_vars) {
+  uint res = 0u;
+  uint const x_10 = atomic_fetch_min_explicit(tint_module_vars.arg_0, 1u, memory_order_relaxed);
+  res = x_10;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicMin_69d383(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_30 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_30, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicOr/storage_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicOr/storage_i32.spvasm.expected.ir.msl
index 40aafa6..cefa4bd 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicOr/storage_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicOr/storage_i32.spvasm.expected.ir.msl
@@ -1,52 +1,28 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_int arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<i32> @offset(0)
+void atomicOr_8d96a0(tint_module_vars_struct tint_module_vars) {
+  int res = 0;
+  int const x_9 = atomic_fetch_or_explicit((&(*tint_module_vars.sb_rw).arg_0), 1, memory_order_relaxed);
+  res = x_9;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicOr_8d96a0(tint_module_vars);
 }
-
-%atomicOr_8d96a0 = func():void {
-  $B2: {
-    %res:ptr<function, i32, read_write> = var, 0i
-    %4:ptr<storage, atomic<i32>, read_write> = access %sb_rw, 0u
-    %5:i32 = atomicOr %4, 1i
-    %x_9:i32 = let %5
-    store %res, %x_9
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %8:void = call %atomicOr_8d96a0
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicOr_8d96a0(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %10:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %12:void = call %atomicOr_8d96a0
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %14:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicOr/storage_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicOr/storage_u32.spvasm.expected.ir.msl
index 42ef410..1064b87 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicOr/storage_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicOr/storage_u32.spvasm.expected.ir.msl
@@ -1,52 +1,28 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_uint arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<u32> @offset(0)
+void atomicOr_5e95d4(tint_module_vars_struct tint_module_vars) {
+  uint res = 0u;
+  uint const x_9 = atomic_fetch_or_explicit((&(*tint_module_vars.sb_rw).arg_0), 1u, memory_order_relaxed);
+  res = x_9;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicOr_5e95d4(tint_module_vars);
 }
-
-%atomicOr_5e95d4 = func():void {
-  $B2: {
-    %res:ptr<function, u32, read_write> = var, 0u
-    %4:ptr<storage, atomic<u32>, read_write> = access %sb_rw, 0u
-    %5:u32 = atomicOr %4, 1u
-    %x_9:u32 = let %5
-    store %res, %x_9
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %8:void = call %atomicOr_5e95d4
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicOr_5e95d4(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %10:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %12:void = call %atomicOr_5e95d4
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %14:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicOr/workgroup_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicOr/workgroup_i32.spvasm.expected.ir.msl
index 49e8313..6caf7f5 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicOr/workgroup_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicOr/workgroup_i32.spvasm.expected.ir.msl
@@ -1,9 +1,37 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_int* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_int tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicOr
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicOr_d09248(tint_module_vars_struct tint_module_vars) {
+  int res = 0;
+  int const x_11 = atomic_fetch_or_explicit(tint_module_vars.arg_0, 1, memory_order_relaxed);
+  res = x_11;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicOr_d09248(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_31 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_31, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicOr/workgroup_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicOr/workgroup_u32.spvasm.expected.ir.msl
index 49e8313..ff6d77a 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicOr/workgroup_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicOr/workgroup_u32.spvasm.expected.ir.msl
@@ -1,9 +1,37 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_uint* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_uint tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicOr
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicOr_5e3d61(tint_module_vars_struct tint_module_vars) {
+  uint res = 0u;
+  uint const x_10 = atomic_fetch_or_explicit(tint_module_vars.arg_0, 1u, memory_order_relaxed);
+  res = x_10;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicOr_5e3d61(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_30 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_30, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicStore/storage_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicStore/storage_i32.spvasm.expected.ir.msl
index b596ede..ec11b1e 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicStore/storage_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicStore/storage_i32.spvasm.expected.ir.msl
@@ -1,49 +1,26 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_int arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<i32> @offset(0)
+void atomicStore_d1e9a6(tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit((&(*tint_module_vars.sb_rw).arg_0), 1, memory_order_relaxed);
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicStore_d1e9a6(tint_module_vars);
 }
-
-%atomicStore_d1e9a6 = func():void {
-  $B2: {
-    %3:ptr<storage, atomic<i32>, read_write> = access %sb_rw, 0u
-    %4:void = atomicStore %3, 1i
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %6:void = call %atomicStore_d1e9a6
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicStore_d1e9a6(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %8:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %10:void = call %atomicStore_d1e9a6
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %12:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicStore/storage_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicStore/storage_u32.spvasm.expected.ir.msl
index f8c29ad..0f574a8 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicStore/storage_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicStore/storage_u32.spvasm.expected.ir.msl
@@ -1,49 +1,26 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_uint arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<u32> @offset(0)
+void atomicStore_cdc29e(tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit((&(*tint_module_vars.sb_rw).arg_0), 1u, memory_order_relaxed);
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicStore_cdc29e(tint_module_vars);
 }
-
-%atomicStore_cdc29e = func():void {
-  $B2: {
-    %3:ptr<storage, atomic<u32>, read_write> = access %sb_rw, 0u
-    %4:void = atomicStore %3, 1u
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %6:void = call %atomicStore_cdc29e
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicStore_cdc29e(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %8:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %10:void = call %atomicStore_cdc29e
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %12:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicStore/workgroup_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicStore/workgroup_i32.spvasm.expected.ir.msl
index 92c0fdd..a0722e9 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicStore/workgroup_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicStore/workgroup_i32.spvasm.expected.ir.msl
@@ -1,9 +1,35 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_int* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_int tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicStore
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicStore_8bea94(tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 1, memory_order_relaxed);
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicStore_8bea94(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_29 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_29, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicStore/workgroup_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicStore/workgroup_u32.spvasm.expected.ir.msl
index 92c0fdd..8deb954 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicStore/workgroup_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicStore/workgroup_u32.spvasm.expected.ir.msl
@@ -1,9 +1,35 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_uint* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_uint tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicStore
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicStore_726882(tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 1u, memory_order_relaxed);
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicStore_726882(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_28 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_28, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicSub/storage_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicSub/storage_i32.spvasm.expected.ir.msl
index 98dc438..4619989 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicSub/storage_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicSub/storage_i32.spvasm.expected.ir.msl
@@ -1,52 +1,28 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_int arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<i32> @offset(0)
+void atomicSub_051100(tint_module_vars_struct tint_module_vars) {
+  int res = 0;
+  int const x_9 = atomic_fetch_sub_explicit((&(*tint_module_vars.sb_rw).arg_0), 1, memory_order_relaxed);
+  res = x_9;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicSub_051100(tint_module_vars);
 }
-
-%atomicSub_051100 = func():void {
-  $B2: {
-    %res:ptr<function, i32, read_write> = var, 0i
-    %4:ptr<storage, atomic<i32>, read_write> = access %sb_rw, 0u
-    %5:i32 = atomicSub %4, 1i
-    %x_9:i32 = let %5
-    store %res, %x_9
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %8:void = call %atomicSub_051100
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicSub_051100(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %10:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %12:void = call %atomicSub_051100
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %14:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicSub/storage_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicSub/storage_u32.spvasm.expected.ir.msl
index 6de10a8..243b548 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicSub/storage_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicSub/storage_u32.spvasm.expected.ir.msl
@@ -1,52 +1,28 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_uint arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<u32> @offset(0)
+void atomicSub_15bfc9(tint_module_vars_struct tint_module_vars) {
+  uint res = 0u;
+  uint const x_9 = atomic_fetch_sub_explicit((&(*tint_module_vars.sb_rw).arg_0), 1u, memory_order_relaxed);
+  res = x_9;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicSub_15bfc9(tint_module_vars);
 }
-
-%atomicSub_15bfc9 = func():void {
-  $B2: {
-    %res:ptr<function, u32, read_write> = var, 0u
-    %4:ptr<storage, atomic<u32>, read_write> = access %sb_rw, 0u
-    %5:u32 = atomicSub %4, 1u
-    %x_9:u32 = let %5
-    store %res, %x_9
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %8:void = call %atomicSub_15bfc9
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicSub_15bfc9(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %10:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %12:void = call %atomicSub_15bfc9
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %14:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicSub/workgroup_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicSub/workgroup_i32.spvasm.expected.ir.msl
index 0c4bcbe..806686c 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicSub/workgroup_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicSub/workgroup_i32.spvasm.expected.ir.msl
@@ -1,9 +1,37 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_int* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_int tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicSub
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicSub_77883a(tint_module_vars_struct tint_module_vars) {
+  int res = 0;
+  int const x_11 = atomic_fetch_sub_explicit(tint_module_vars.arg_0, 1, memory_order_relaxed);
+  res = x_11;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicSub_77883a(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_31 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_31, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicSub/workgroup_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicSub/workgroup_u32.spvasm.expected.ir.msl
index 0c4bcbe..fa64f63 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicSub/workgroup_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicSub/workgroup_u32.spvasm.expected.ir.msl
@@ -1,9 +1,37 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_uint* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_uint tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicSub
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicSub_0d26c2(tint_module_vars_struct tint_module_vars) {
+  uint res = 0u;
+  uint const x_10 = atomic_fetch_sub_explicit(tint_module_vars.arg_0, 1u, memory_order_relaxed);
+  res = x_10;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicSub_0d26c2(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_30 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_30, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicXor/storage_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicXor/storage_i32.spvasm.expected.ir.msl
index 532c62c..a2682f5 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicXor/storage_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicXor/storage_i32.spvasm.expected.ir.msl
@@ -1,52 +1,28 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_int arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<i32> @offset(0)
+void atomicXor_c1b78c(tint_module_vars_struct tint_module_vars) {
+  int res = 0;
+  int const x_9 = atomic_fetch_xor_explicit((&(*tint_module_vars.sb_rw).arg_0), 1, memory_order_relaxed);
+  res = x_9;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicXor_c1b78c(tint_module_vars);
 }
-
-%atomicXor_c1b78c = func():void {
-  $B2: {
-    %res:ptr<function, i32, read_write> = var, 0i
-    %4:ptr<storage, atomic<i32>, read_write> = access %sb_rw, 0u
-    %5:i32 = atomicXor %4, 1i
-    %x_9:i32 = let %5
-    store %res, %x_9
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %8:void = call %atomicXor_c1b78c
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicXor_c1b78c(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %10:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %12:void = call %atomicXor_c1b78c
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %14:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicXor/storage_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicXor/storage_u32.spvasm.expected.ir.msl
index c123f78..eca0011 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicXor/storage_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicXor/storage_u32.spvasm.expected.ir.msl
@@ -1,52 +1,28 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_uint arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<u32> @offset(0)
+void atomicXor_54510e(tint_module_vars_struct tint_module_vars) {
+  uint res = 0u;
+  uint const x_9 = atomic_fetch_xor_explicit((&(*tint_module_vars.sb_rw).arg_0), 1u, memory_order_relaxed);
+  res = x_9;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicXor_54510e(tint_module_vars);
 }
-
-%atomicXor_54510e = func():void {
-  $B2: {
-    %res:ptr<function, u32, read_write> = var, 0u
-    %4:ptr<storage, atomic<u32>, read_write> = access %sb_rw, 0u
-    %5:u32 = atomicXor %4, 1u
-    %x_9:u32 = let %5
-    store %res, %x_9
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %8:void = call %atomicXor_54510e
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicXor_54510e(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %10:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %12:void = call %atomicXor_54510e
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %14:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicXor/workgroup_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicXor/workgroup_i32.spvasm.expected.ir.msl
index 665f64b..0df34ac 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicXor/workgroup_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicXor/workgroup_i32.spvasm.expected.ir.msl
@@ -1,9 +1,37 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_int* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_int tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicXor
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicXor_75dc95(tint_module_vars_struct tint_module_vars) {
+  int res = 0;
+  int const x_11 = atomic_fetch_xor_explicit(tint_module_vars.arg_0, 1, memory_order_relaxed);
+  res = x_11;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicXor_75dc95(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_31 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_31, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/literal/atomicXor/workgroup_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/atomicXor/workgroup_u32.spvasm.expected.ir.msl
index 665f64b..50b79fe 100644
--- a/test/tint/builtins/atomics/from_gen/literal/atomicXor/workgroup_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/atomicXor/workgroup_u32.spvasm.expected.ir.msl
@@ -1,9 +1,37 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_uint* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_uint tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicXor
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicXor_c8e6be(tint_module_vars_struct tint_module_vars) {
+  uint res = 0u;
+  uint const x_10 = atomic_fetch_xor_explicit(tint_module_vars.arg_0, 1u, memory_order_relaxed);
+  res = x_10;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicXor_c8e6be(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_30 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_30, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/literal/spvAtomicDecrement/storage_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/spvAtomicDecrement/storage_i32.spvasm.expected.ir.msl
index 0b67cf6..def7052 100644
--- a/test/tint/builtins/atomics/from_gen/literal/spvAtomicDecrement/storage_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/spvAtomicDecrement/storage_i32.spvasm.expected.ir.msl
@@ -1,52 +1,28 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_int arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<i32> @offset(0)
+void atomicAdd_d32fe4(tint_module_vars_struct tint_module_vars) {
+  int res = 0;
+  int const x_9 = atomic_fetch_sub_explicit((&(*tint_module_vars.sb_rw).arg_0), 1, memory_order_relaxed);
+  res = x_9;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAdd_d32fe4(tint_module_vars);
 }
-
-%atomicAdd_d32fe4 = func():void {
-  $B2: {
-    %res:ptr<function, i32, read_write> = var, 0i
-    %4:ptr<storage, atomic<i32>, read_write> = access %sb_rw, 0u
-    %5:i32 = atomicSub %4, 1i
-    %x_9:i32 = let %5
-    store %res, %x_9
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %8:void = call %atomicAdd_d32fe4
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAdd_d32fe4(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %10:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %12:void = call %atomicAdd_d32fe4
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %14:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/literal/spvAtomicDecrement/storage_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/spvAtomicDecrement/storage_u32.spvasm.expected.ir.msl
index 68ccea4..47bdbea 100644
--- a/test/tint/builtins/atomics/from_gen/literal/spvAtomicDecrement/storage_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/spvAtomicDecrement/storage_u32.spvasm.expected.ir.msl
@@ -1,52 +1,28 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_uint arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<u32> @offset(0)
+void atomicAdd_8a199a(tint_module_vars_struct tint_module_vars) {
+  uint res = 0u;
+  uint const x_9 = atomic_fetch_sub_explicit((&(*tint_module_vars.sb_rw).arg_0), 1u, memory_order_relaxed);
+  res = x_9;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAdd_8a199a(tint_module_vars);
 }
-
-%atomicAdd_8a199a = func():void {
-  $B2: {
-    %res:ptr<function, u32, read_write> = var, 0u
-    %4:ptr<storage, atomic<u32>, read_write> = access %sb_rw, 0u
-    %5:u32 = atomicSub %4, 1u
-    %x_9:u32 = let %5
-    store %res, %x_9
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %8:void = call %atomicAdd_8a199a
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAdd_8a199a(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %10:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %12:void = call %atomicAdd_8a199a
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %14:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/literal/spvAtomicDecrement/workgroup_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/spvAtomicDecrement/workgroup_i32.spvasm.expected.ir.msl
index 0c4bcbe..a47c762 100644
--- a/test/tint/builtins/atomics/from_gen/literal/spvAtomicDecrement/workgroup_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/spvAtomicDecrement/workgroup_i32.spvasm.expected.ir.msl
@@ -1,9 +1,37 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_int* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_int tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicSub
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicAdd_794055(tint_module_vars_struct tint_module_vars) {
+  int res = 0;
+  int const x_11 = atomic_fetch_sub_explicit(tint_module_vars.arg_0, 1, memory_order_relaxed);
+  res = x_11;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicAdd_794055(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_31 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_31, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/literal/spvAtomicDecrement/workgroup_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/spvAtomicDecrement/workgroup_u32.spvasm.expected.ir.msl
index 0c4bcbe..29b3d5a 100644
--- a/test/tint/builtins/atomics/from_gen/literal/spvAtomicDecrement/workgroup_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/spvAtomicDecrement/workgroup_u32.spvasm.expected.ir.msl
@@ -1,9 +1,37 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_uint* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_uint tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicSub
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicAdd_d5db1d(tint_module_vars_struct tint_module_vars) {
+  uint res = 0u;
+  uint const x_10 = atomic_fetch_sub_explicit(tint_module_vars.arg_0, 1u, memory_order_relaxed);
+  res = x_10;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicAdd_d5db1d(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_30 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_30, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/literal/spvAtomicIncrement/storage_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/spvAtomicIncrement/storage_i32.spvasm.expected.ir.msl
index 68658f0..0c74870 100644
--- a/test/tint/builtins/atomics/from_gen/literal/spvAtomicIncrement/storage_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/spvAtomicIncrement/storage_i32.spvasm.expected.ir.msl
@@ -1,52 +1,28 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_int arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<i32> @offset(0)
+void atomicAdd_d32fe4(tint_module_vars_struct tint_module_vars) {
+  int res = 0;
+  int const x_9 = atomic_fetch_add_explicit((&(*tint_module_vars.sb_rw).arg_0), 1, memory_order_relaxed);
+  res = x_9;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAdd_d32fe4(tint_module_vars);
 }
-
-%atomicAdd_d32fe4 = func():void {
-  $B2: {
-    %res:ptr<function, i32, read_write> = var, 0i
-    %4:ptr<storage, atomic<i32>, read_write> = access %sb_rw, 0u
-    %5:i32 = atomicAdd %4, 1i
-    %x_9:i32 = let %5
-    store %res, %x_9
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %8:void = call %atomicAdd_d32fe4
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAdd_d32fe4(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %10:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %12:void = call %atomicAdd_d32fe4
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %14:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/literal/spvAtomicIncrement/storage_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/spvAtomicIncrement/storage_u32.spvasm.expected.ir.msl
index 1375ee3..f76e4d6 100644
--- a/test/tint/builtins/atomics/from_gen/literal/spvAtomicIncrement/storage_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/spvAtomicIncrement/storage_u32.spvasm.expected.ir.msl
@@ -1,52 +1,28 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_uint arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<u32> @offset(0)
+void atomicAdd_8a199a(tint_module_vars_struct tint_module_vars) {
+  uint res = 0u;
+  uint const x_9 = atomic_fetch_add_explicit((&(*tint_module_vars.sb_rw).arg_0), 1u, memory_order_relaxed);
+  res = x_9;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAdd_8a199a(tint_module_vars);
 }
-
-%atomicAdd_8a199a = func():void {
-  $B2: {
-    %res:ptr<function, u32, read_write> = var, 0u
-    %4:ptr<storage, atomic<u32>, read_write> = access %sb_rw, 0u
-    %5:u32 = atomicAdd %4, 1u
-    %x_9:u32 = let %5
-    store %res, %x_9
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %8:void = call %atomicAdd_8a199a
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAdd_8a199a(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %10:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %12:void = call %atomicAdd_8a199a
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %14:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/literal/spvAtomicIncrement/workgroup_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/spvAtomicIncrement/workgroup_i32.spvasm.expected.ir.msl
index f7dc0d0..af1ce0c 100644
--- a/test/tint/builtins/atomics/from_gen/literal/spvAtomicIncrement/workgroup_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/spvAtomicIncrement/workgroup_i32.spvasm.expected.ir.msl
@@ -1,9 +1,37 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_int* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_int tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicAdd
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicAdd_794055(tint_module_vars_struct tint_module_vars) {
+  int res = 0;
+  int const x_11 = atomic_fetch_add_explicit(tint_module_vars.arg_0, 1, memory_order_relaxed);
+  res = x_11;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicAdd_794055(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_31 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_31, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/literal/spvAtomicIncrement/workgroup_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/literal/spvAtomicIncrement/workgroup_u32.spvasm.expected.ir.msl
index f7dc0d0..b826e33 100644
--- a/test/tint/builtins/atomics/from_gen/literal/spvAtomicIncrement/workgroup_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/literal/spvAtomicIncrement/workgroup_u32.spvasm.expected.ir.msl
@@ -1,9 +1,37 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_uint* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_uint tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicAdd
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicAdd_d5db1d(tint_module_vars_struct tint_module_vars) {
+  uint res = 0u;
+  uint const x_10 = atomic_fetch_add_explicit(tint_module_vars.arg_0, 1u, memory_order_relaxed);
+  res = x_10;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicAdd_d5db1d(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_30 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_30, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicAdd/storage_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicAdd/storage_i32.spvasm.expected.ir.msl
index 8a8ef46..9712db7 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicAdd/storage_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicAdd/storage_i32.spvasm.expected.ir.msl
@@ -1,56 +1,31 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_int arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<i32> @offset(0)
+void atomicAdd_d32fe4(tint_module_vars_struct tint_module_vars) {
+  int arg_1 = 0;
+  int res = 0;
+  arg_1 = 1;
+  int const x_20 = arg_1;
+  int const x_13 = atomic_fetch_add_explicit((&(*tint_module_vars.sb_rw).arg_0), x_20, memory_order_relaxed);
+  res = x_13;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAdd_d32fe4(tint_module_vars);
 }
-
-%atomicAdd_d32fe4 = func():void {
-  $B2: {
-    %arg_1:ptr<function, i32, read_write> = var, 0i
-    %res:ptr<function, i32, read_write> = var, 0i
-    store %arg_1, 1i
-    %5:i32 = load %arg_1
-    %x_20:i32 = let %5
-    %7:ptr<storage, atomic<i32>, read_write> = access %sb_rw, 0u
-    %8:i32 = atomicAdd %7, %x_20
-    %x_13:i32 = let %8
-    store %res, %x_13
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %11:void = call %atomicAdd_d32fe4
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAdd_d32fe4(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %13:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %15:void = call %atomicAdd_d32fe4
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %17:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicAdd/storage_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicAdd/storage_u32.spvasm.expected.ir.msl
index 19e1415..a1645bc 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicAdd/storage_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicAdd/storage_u32.spvasm.expected.ir.msl
@@ -1,56 +1,31 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_uint arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<u32> @offset(0)
+void atomicAdd_8a199a(tint_module_vars_struct tint_module_vars) {
+  uint arg_1 = 0u;
+  uint res = 0u;
+  arg_1 = 1u;
+  uint const x_18 = arg_1;
+  uint const x_13 = atomic_fetch_add_explicit((&(*tint_module_vars.sb_rw).arg_0), x_18, memory_order_relaxed);
+  res = x_13;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAdd_8a199a(tint_module_vars);
 }
-
-%atomicAdd_8a199a = func():void {
-  $B2: {
-    %arg_1:ptr<function, u32, read_write> = var, 0u
-    %res:ptr<function, u32, read_write> = var, 0u
-    store %arg_1, 1u
-    %5:u32 = load %arg_1
-    %x_18:u32 = let %5
-    %7:ptr<storage, atomic<u32>, read_write> = access %sb_rw, 0u
-    %8:u32 = atomicAdd %7, %x_18
-    %x_13:u32 = let %8
-    store %res, %x_13
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %11:void = call %atomicAdd_8a199a
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAdd_8a199a(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %13:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %15:void = call %atomicAdd_8a199a
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %17:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicAdd/workgroup_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicAdd/workgroup_i32.spvasm.expected.ir.msl
index f7dc0d0..39d7e43 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicAdd/workgroup_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicAdd/workgroup_i32.spvasm.expected.ir.msl
@@ -1,9 +1,40 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_int* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_int tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicAdd
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicAdd_794055(tint_module_vars_struct tint_module_vars) {
+  int arg_1 = 0;
+  int res = 0;
+  arg_1 = 1;
+  int const x_19 = arg_1;
+  int const x_15 = atomic_fetch_add_explicit(tint_module_vars.arg_0, x_19, memory_order_relaxed);
+  res = x_15;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicAdd_794055(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_33 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_33, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicAdd/workgroup_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicAdd/workgroup_u32.spvasm.expected.ir.msl
index f7dc0d0..aa1213c 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicAdd/workgroup_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicAdd/workgroup_u32.spvasm.expected.ir.msl
@@ -1,9 +1,40 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_uint* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_uint tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicAdd
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicAdd_d5db1d(tint_module_vars_struct tint_module_vars) {
+  uint arg_1 = 0u;
+  uint res = 0u;
+  arg_1 = 1u;
+  uint const x_18 = arg_1;
+  uint const x_14 = atomic_fetch_add_explicit(tint_module_vars.arg_0, x_18, memory_order_relaxed);
+  res = x_14;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicAdd_d5db1d(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_32 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_32, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicAnd/storage_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicAnd/storage_i32.spvasm.expected.ir.msl
index 62a0403..0d1a7a3 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicAnd/storage_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicAnd/storage_i32.spvasm.expected.ir.msl
@@ -1,56 +1,31 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_int arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<i32> @offset(0)
+void atomicAnd_152966(tint_module_vars_struct tint_module_vars) {
+  int arg_1 = 0;
+  int res = 0;
+  arg_1 = 1;
+  int const x_20 = arg_1;
+  int const x_13 = atomic_fetch_and_explicit((&(*tint_module_vars.sb_rw).arg_0), x_20, memory_order_relaxed);
+  res = x_13;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAnd_152966(tint_module_vars);
 }
-
-%atomicAnd_152966 = func():void {
-  $B2: {
-    %arg_1:ptr<function, i32, read_write> = var, 0i
-    %res:ptr<function, i32, read_write> = var, 0i
-    store %arg_1, 1i
-    %5:i32 = load %arg_1
-    %x_20:i32 = let %5
-    %7:ptr<storage, atomic<i32>, read_write> = access %sb_rw, 0u
-    %8:i32 = atomicAnd %7, %x_20
-    %x_13:i32 = let %8
-    store %res, %x_13
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %11:void = call %atomicAnd_152966
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAnd_152966(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %13:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %15:void = call %atomicAnd_152966
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %17:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicAnd/storage_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicAnd/storage_u32.spvasm.expected.ir.msl
index b578acb..090f7ab 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicAnd/storage_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicAnd/storage_u32.spvasm.expected.ir.msl
@@ -1,56 +1,31 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_uint arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<u32> @offset(0)
+void atomicAnd_85a8d9(tint_module_vars_struct tint_module_vars) {
+  uint arg_1 = 0u;
+  uint res = 0u;
+  arg_1 = 1u;
+  uint const x_18 = arg_1;
+  uint const x_13 = atomic_fetch_and_explicit((&(*tint_module_vars.sb_rw).arg_0), x_18, memory_order_relaxed);
+  res = x_13;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAnd_85a8d9(tint_module_vars);
 }
-
-%atomicAnd_85a8d9 = func():void {
-  $B2: {
-    %arg_1:ptr<function, u32, read_write> = var, 0u
-    %res:ptr<function, u32, read_write> = var, 0u
-    store %arg_1, 1u
-    %5:u32 = load %arg_1
-    %x_18:u32 = let %5
-    %7:ptr<storage, atomic<u32>, read_write> = access %sb_rw, 0u
-    %8:u32 = atomicAnd %7, %x_18
-    %x_13:u32 = let %8
-    store %res, %x_13
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %11:void = call %atomicAnd_85a8d9
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAnd_85a8d9(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %13:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %15:void = call %atomicAnd_85a8d9
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %17:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicAnd/workgroup_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicAnd/workgroup_i32.spvasm.expected.ir.msl
index cb4c94c..65c6e4f 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicAnd/workgroup_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicAnd/workgroup_i32.spvasm.expected.ir.msl
@@ -1,9 +1,40 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_int* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_int tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicAnd
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicAnd_45a819(tint_module_vars_struct tint_module_vars) {
+  int arg_1 = 0;
+  int res = 0;
+  arg_1 = 1;
+  int const x_19 = arg_1;
+  int const x_15 = atomic_fetch_and_explicit(tint_module_vars.arg_0, x_19, memory_order_relaxed);
+  res = x_15;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicAnd_45a819(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_33 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_33, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicAnd/workgroup_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicAnd/workgroup_u32.spvasm.expected.ir.msl
index cb4c94c..395d925 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicAnd/workgroup_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicAnd/workgroup_u32.spvasm.expected.ir.msl
@@ -1,9 +1,40 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_uint* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_uint tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicAnd
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicAnd_34edd3(tint_module_vars_struct tint_module_vars) {
+  uint arg_1 = 0u;
+  uint res = 0u;
+  arg_1 = 1u;
+  uint const x_18 = arg_1;
+  uint const x_14 = atomic_fetch_and_explicit(tint_module_vars.arg_0, x_18, memory_order_relaxed);
+  res = x_14;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicAnd_34edd3(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_32 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_32, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicExchange/storage_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicExchange/storage_i32.spvasm.expected.ir.msl
index b48794d..7eded40 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicExchange/storage_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicExchange/storage_i32.spvasm.expected.ir.msl
@@ -1,56 +1,31 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_int arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<i32> @offset(0)
+void atomicExchange_f2e22f(tint_module_vars_struct tint_module_vars) {
+  int arg_1 = 0;
+  int res = 0;
+  arg_1 = 1;
+  int const x_20 = arg_1;
+  int const x_13 = atomic_exchange_explicit((&(*tint_module_vars.sb_rw).arg_0), x_20, memory_order_relaxed);
+  res = x_13;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicExchange_f2e22f(tint_module_vars);
 }
-
-%atomicExchange_f2e22f = func():void {
-  $B2: {
-    %arg_1:ptr<function, i32, read_write> = var, 0i
-    %res:ptr<function, i32, read_write> = var, 0i
-    store %arg_1, 1i
-    %5:i32 = load %arg_1
-    %x_20:i32 = let %5
-    %7:ptr<storage, atomic<i32>, read_write> = access %sb_rw, 0u
-    %8:i32 = atomicExchange %7, %x_20
-    %x_13:i32 = let %8
-    store %res, %x_13
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %11:void = call %atomicExchange_f2e22f
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicExchange_f2e22f(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %13:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %15:void = call %atomicExchange_f2e22f
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %17:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicExchange/storage_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicExchange/storage_u32.spvasm.expected.ir.msl
index df1b5e9..bdf83bb 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicExchange/storage_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicExchange/storage_u32.spvasm.expected.ir.msl
@@ -1,56 +1,31 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_uint arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<u32> @offset(0)
+void atomicExchange_d59712(tint_module_vars_struct tint_module_vars) {
+  uint arg_1 = 0u;
+  uint res = 0u;
+  arg_1 = 1u;
+  uint const x_18 = arg_1;
+  uint const x_13 = atomic_exchange_explicit((&(*tint_module_vars.sb_rw).arg_0), x_18, memory_order_relaxed);
+  res = x_13;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicExchange_d59712(tint_module_vars);
 }
-
-%atomicExchange_d59712 = func():void {
-  $B2: {
-    %arg_1:ptr<function, u32, read_write> = var, 0u
-    %res:ptr<function, u32, read_write> = var, 0u
-    store %arg_1, 1u
-    %5:u32 = load %arg_1
-    %x_18:u32 = let %5
-    %7:ptr<storage, atomic<u32>, read_write> = access %sb_rw, 0u
-    %8:u32 = atomicExchange %7, %x_18
-    %x_13:u32 = let %8
-    store %res, %x_13
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %11:void = call %atomicExchange_d59712
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicExchange_d59712(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %13:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %15:void = call %atomicExchange_d59712
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %17:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicExchange/workgroup_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicExchange/workgroup_i32.spvasm.expected.ir.msl
index 2f8d44e..4cb082b6 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicExchange/workgroup_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicExchange/workgroup_i32.spvasm.expected.ir.msl
@@ -1,9 +1,40 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_int* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_int tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicExchange
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicExchange_e114ba(tint_module_vars_struct tint_module_vars) {
+  int arg_1 = 0;
+  int res = 0;
+  arg_1 = 1;
+  int const x_19 = arg_1;
+  int const x_15 = atomic_exchange_explicit(tint_module_vars.arg_0, x_19, memory_order_relaxed);
+  res = x_15;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicExchange_e114ba(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_33 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_33, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicExchange/workgroup_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicExchange/workgroup_u32.spvasm.expected.ir.msl
index 2f8d44e..bb30cae 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicExchange/workgroup_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicExchange/workgroup_u32.spvasm.expected.ir.msl
@@ -1,9 +1,40 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_uint* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_uint tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicExchange
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicExchange_0a5dca(tint_module_vars_struct tint_module_vars) {
+  uint arg_1 = 0u;
+  uint res = 0u;
+  arg_1 = 1u;
+  uint const x_18 = arg_1;
+  uint const x_14 = atomic_exchange_explicit(tint_module_vars.arg_0, x_18, memory_order_relaxed);
+  res = x_14;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicExchange_0a5dca(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_32 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_32, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicLoad/storage_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicLoad/storage_i32.spvasm.expected.ir.msl
index 7b20853..18eb9c8 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicLoad/storage_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicLoad/storage_i32.spvasm.expected.ir.msl
@@ -1,52 +1,28 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_int arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<i32> @offset(0)
+void atomicLoad_0806ad(tint_module_vars_struct tint_module_vars) {
+  int res = 0;
+  int const x_9 = atomic_load_explicit((&(*tint_module_vars.sb_rw).arg_0), memory_order_relaxed);
+  res = x_9;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicLoad_0806ad(tint_module_vars);
 }
-
-%atomicLoad_0806ad = func():void {
-  $B2: {
-    %res:ptr<function, i32, read_write> = var, 0i
-    %4:ptr<storage, atomic<i32>, read_write> = access %sb_rw, 0u
-    %5:i32 = atomicLoad %4
-    %x_9:i32 = let %5
-    store %res, %x_9
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %8:void = call %atomicLoad_0806ad
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicLoad_0806ad(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %10:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %12:void = call %atomicLoad_0806ad
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %14:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicLoad/storage_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicLoad/storage_u32.spvasm.expected.ir.msl
index 3c25b76..da2266a 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicLoad/storage_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicLoad/storage_u32.spvasm.expected.ir.msl
@@ -1,52 +1,28 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_uint arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<u32> @offset(0)
+void atomicLoad_fe6cc3(tint_module_vars_struct tint_module_vars) {
+  uint res = 0u;
+  uint const x_9 = atomic_load_explicit((&(*tint_module_vars.sb_rw).arg_0), memory_order_relaxed);
+  res = x_9;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicLoad_fe6cc3(tint_module_vars);
 }
-
-%atomicLoad_fe6cc3 = func():void {
-  $B2: {
-    %res:ptr<function, u32, read_write> = var, 0u
-    %4:ptr<storage, atomic<u32>, read_write> = access %sb_rw, 0u
-    %5:u32 = atomicLoad %4
-    %x_9:u32 = let %5
-    store %res, %x_9
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %8:void = call %atomicLoad_fe6cc3
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicLoad_fe6cc3(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %10:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %12:void = call %atomicLoad_fe6cc3
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %14:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicLoad/workgroup_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicLoad/workgroup_i32.spvasm.expected.ir.msl
index e62fe24..4f2c6fb 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicLoad/workgroup_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicLoad/workgroup_i32.spvasm.expected.ir.msl
@@ -1,9 +1,37 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_int* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_int tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicLoad
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicLoad_afcc03(tint_module_vars_struct tint_module_vars) {
+  int res = 0;
+  int const x_11 = atomic_load_explicit(tint_module_vars.arg_0, memory_order_relaxed);
+  res = x_11;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicLoad_afcc03(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_30 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_30, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicLoad/workgroup_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicLoad/workgroup_u32.spvasm.expected.ir.msl
index e62fe24..6dc06c4 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicLoad/workgroup_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicLoad/workgroup_u32.spvasm.expected.ir.msl
@@ -1,9 +1,37 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_uint* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_uint tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicLoad
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicLoad_361bf1(tint_module_vars_struct tint_module_vars) {
+  uint res = 0u;
+  uint const x_10 = atomic_load_explicit(tint_module_vars.arg_0, memory_order_relaxed);
+  res = x_10;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicLoad_361bf1(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_29 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_29, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicMax/storage_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicMax/storage_i32.spvasm.expected.ir.msl
index 44332aa..b013ae6 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicMax/storage_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicMax/storage_i32.spvasm.expected.ir.msl
@@ -1,56 +1,31 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_int arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<i32> @offset(0)
+void atomicMax_92aa72(tint_module_vars_struct tint_module_vars) {
+  int arg_1 = 0;
+  int res = 0;
+  arg_1 = 1;
+  int const x_20 = arg_1;
+  int const x_13 = atomic_fetch_max_explicit((&(*tint_module_vars.sb_rw).arg_0), x_20, memory_order_relaxed);
+  res = x_13;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicMax_92aa72(tint_module_vars);
 }
-
-%atomicMax_92aa72 = func():void {
-  $B2: {
-    %arg_1:ptr<function, i32, read_write> = var, 0i
-    %res:ptr<function, i32, read_write> = var, 0i
-    store %arg_1, 1i
-    %5:i32 = load %arg_1
-    %x_20:i32 = let %5
-    %7:ptr<storage, atomic<i32>, read_write> = access %sb_rw, 0u
-    %8:i32 = atomicMax %7, %x_20
-    %x_13:i32 = let %8
-    store %res, %x_13
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %11:void = call %atomicMax_92aa72
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicMax_92aa72(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %13:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %15:void = call %atomicMax_92aa72
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %17:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicMax/storage_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicMax/storage_u32.spvasm.expected.ir.msl
index 2c71acf..745e913 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicMax/storage_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicMax/storage_u32.spvasm.expected.ir.msl
@@ -1,56 +1,31 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_uint arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<u32> @offset(0)
+void atomicMax_51b9be(tint_module_vars_struct tint_module_vars) {
+  uint arg_1 = 0u;
+  uint res = 0u;
+  arg_1 = 1u;
+  uint const x_18 = arg_1;
+  uint const x_13 = atomic_fetch_max_explicit((&(*tint_module_vars.sb_rw).arg_0), x_18, memory_order_relaxed);
+  res = x_13;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicMax_51b9be(tint_module_vars);
 }
-
-%atomicMax_51b9be = func():void {
-  $B2: {
-    %arg_1:ptr<function, u32, read_write> = var, 0u
-    %res:ptr<function, u32, read_write> = var, 0u
-    store %arg_1, 1u
-    %5:u32 = load %arg_1
-    %x_18:u32 = let %5
-    %7:ptr<storage, atomic<u32>, read_write> = access %sb_rw, 0u
-    %8:u32 = atomicMax %7, %x_18
-    %x_13:u32 = let %8
-    store %res, %x_13
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %11:void = call %atomicMax_51b9be
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicMax_51b9be(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %13:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %15:void = call %atomicMax_51b9be
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %17:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicMax/workgroup_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicMax/workgroup_i32.spvasm.expected.ir.msl
index 6687606..b240a59 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicMax/workgroup_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicMax/workgroup_i32.spvasm.expected.ir.msl
@@ -1,9 +1,40 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_int* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_int tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicMax
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicMax_a89cc3(tint_module_vars_struct tint_module_vars) {
+  int arg_1 = 0;
+  int res = 0;
+  arg_1 = 1;
+  int const x_19 = arg_1;
+  int const x_15 = atomic_fetch_max_explicit(tint_module_vars.arg_0, x_19, memory_order_relaxed);
+  res = x_15;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicMax_a89cc3(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_33 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_33, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicMax/workgroup_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicMax/workgroup_u32.spvasm.expected.ir.msl
index 6687606..1d384fb 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicMax/workgroup_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicMax/workgroup_u32.spvasm.expected.ir.msl
@@ -1,9 +1,40 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_uint* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_uint tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicMax
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicMax_beccfc(tint_module_vars_struct tint_module_vars) {
+  uint arg_1 = 0u;
+  uint res = 0u;
+  arg_1 = 1u;
+  uint const x_18 = arg_1;
+  uint const x_14 = atomic_fetch_max_explicit(tint_module_vars.arg_0, x_18, memory_order_relaxed);
+  res = x_14;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicMax_beccfc(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_32 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_32, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicMin/storage_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicMin/storage_i32.spvasm.expected.ir.msl
index 0102605..5418f8e 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicMin/storage_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicMin/storage_i32.spvasm.expected.ir.msl
@@ -1,56 +1,31 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_int arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<i32> @offset(0)
+void atomicMin_8e38dc(tint_module_vars_struct tint_module_vars) {
+  int arg_1 = 0;
+  int res = 0;
+  arg_1 = 1;
+  int const x_20 = arg_1;
+  int const x_13 = atomic_fetch_min_explicit((&(*tint_module_vars.sb_rw).arg_0), x_20, memory_order_relaxed);
+  res = x_13;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicMin_8e38dc(tint_module_vars);
 }
-
-%atomicMin_8e38dc = func():void {
-  $B2: {
-    %arg_1:ptr<function, i32, read_write> = var, 0i
-    %res:ptr<function, i32, read_write> = var, 0i
-    store %arg_1, 1i
-    %5:i32 = load %arg_1
-    %x_20:i32 = let %5
-    %7:ptr<storage, atomic<i32>, read_write> = access %sb_rw, 0u
-    %8:i32 = atomicMin %7, %x_20
-    %x_13:i32 = let %8
-    store %res, %x_13
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %11:void = call %atomicMin_8e38dc
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicMin_8e38dc(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %13:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %15:void = call %atomicMin_8e38dc
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %17:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicMin/storage_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicMin/storage_u32.spvasm.expected.ir.msl
index ce2c985..02e28db 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicMin/storage_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicMin/storage_u32.spvasm.expected.ir.msl
@@ -1,56 +1,31 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_uint arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<u32> @offset(0)
+void atomicMin_c67a74(tint_module_vars_struct tint_module_vars) {
+  uint arg_1 = 0u;
+  uint res = 0u;
+  arg_1 = 1u;
+  uint const x_18 = arg_1;
+  uint const x_13 = atomic_fetch_min_explicit((&(*tint_module_vars.sb_rw).arg_0), x_18, memory_order_relaxed);
+  res = x_13;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicMin_c67a74(tint_module_vars);
 }
-
-%atomicMin_c67a74 = func():void {
-  $B2: {
-    %arg_1:ptr<function, u32, read_write> = var, 0u
-    %res:ptr<function, u32, read_write> = var, 0u
-    store %arg_1, 1u
-    %5:u32 = load %arg_1
-    %x_18:u32 = let %5
-    %7:ptr<storage, atomic<u32>, read_write> = access %sb_rw, 0u
-    %8:u32 = atomicMin %7, %x_18
-    %x_13:u32 = let %8
-    store %res, %x_13
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %11:void = call %atomicMin_c67a74
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicMin_c67a74(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %13:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %15:void = call %atomicMin_c67a74
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %17:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicMin/workgroup_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicMin/workgroup_i32.spvasm.expected.ir.msl
index 829342e..9cda85f 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicMin/workgroup_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicMin/workgroup_i32.spvasm.expected.ir.msl
@@ -1,9 +1,40 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_int* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_int tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicMin
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicMin_278235(tint_module_vars_struct tint_module_vars) {
+  int arg_1 = 0;
+  int res = 0;
+  arg_1 = 1;
+  int const x_19 = arg_1;
+  int const x_15 = atomic_fetch_min_explicit(tint_module_vars.arg_0, x_19, memory_order_relaxed);
+  res = x_15;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicMin_278235(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_33 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_33, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicMin/workgroup_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicMin/workgroup_u32.spvasm.expected.ir.msl
index 829342e..dee163a 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicMin/workgroup_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicMin/workgroup_u32.spvasm.expected.ir.msl
@@ -1,9 +1,40 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_uint* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_uint tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicMin
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicMin_69d383(tint_module_vars_struct tint_module_vars) {
+  uint arg_1 = 0u;
+  uint res = 0u;
+  arg_1 = 1u;
+  uint const x_18 = arg_1;
+  uint const x_14 = atomic_fetch_min_explicit(tint_module_vars.arg_0, x_18, memory_order_relaxed);
+  res = x_14;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicMin_69d383(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_32 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_32, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicOr/storage_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicOr/storage_i32.spvasm.expected.ir.msl
index 9cade54..228ccf0 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicOr/storage_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicOr/storage_i32.spvasm.expected.ir.msl
@@ -1,56 +1,31 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_int arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<i32> @offset(0)
+void atomicOr_8d96a0(tint_module_vars_struct tint_module_vars) {
+  int arg_1 = 0;
+  int res = 0;
+  arg_1 = 1;
+  int const x_20 = arg_1;
+  int const x_13 = atomic_fetch_or_explicit((&(*tint_module_vars.sb_rw).arg_0), x_20, memory_order_relaxed);
+  res = x_13;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicOr_8d96a0(tint_module_vars);
 }
-
-%atomicOr_8d96a0 = func():void {
-  $B2: {
-    %arg_1:ptr<function, i32, read_write> = var, 0i
-    %res:ptr<function, i32, read_write> = var, 0i
-    store %arg_1, 1i
-    %5:i32 = load %arg_1
-    %x_20:i32 = let %5
-    %7:ptr<storage, atomic<i32>, read_write> = access %sb_rw, 0u
-    %8:i32 = atomicOr %7, %x_20
-    %x_13:i32 = let %8
-    store %res, %x_13
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %11:void = call %atomicOr_8d96a0
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicOr_8d96a0(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %13:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %15:void = call %atomicOr_8d96a0
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %17:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicOr/storage_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicOr/storage_u32.spvasm.expected.ir.msl
index dcfab64..c659453 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicOr/storage_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicOr/storage_u32.spvasm.expected.ir.msl
@@ -1,56 +1,31 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_uint arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<u32> @offset(0)
+void atomicOr_5e95d4(tint_module_vars_struct tint_module_vars) {
+  uint arg_1 = 0u;
+  uint res = 0u;
+  arg_1 = 1u;
+  uint const x_18 = arg_1;
+  uint const x_13 = atomic_fetch_or_explicit((&(*tint_module_vars.sb_rw).arg_0), x_18, memory_order_relaxed);
+  res = x_13;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicOr_5e95d4(tint_module_vars);
 }
-
-%atomicOr_5e95d4 = func():void {
-  $B2: {
-    %arg_1:ptr<function, u32, read_write> = var, 0u
-    %res:ptr<function, u32, read_write> = var, 0u
-    store %arg_1, 1u
-    %5:u32 = load %arg_1
-    %x_18:u32 = let %5
-    %7:ptr<storage, atomic<u32>, read_write> = access %sb_rw, 0u
-    %8:u32 = atomicOr %7, %x_18
-    %x_13:u32 = let %8
-    store %res, %x_13
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %11:void = call %atomicOr_5e95d4
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicOr_5e95d4(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %13:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %15:void = call %atomicOr_5e95d4
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %17:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicOr/workgroup_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicOr/workgroup_i32.spvasm.expected.ir.msl
index 49e8313..6450ec5 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicOr/workgroup_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicOr/workgroup_i32.spvasm.expected.ir.msl
@@ -1,9 +1,40 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_int* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_int tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicOr
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicOr_d09248(tint_module_vars_struct tint_module_vars) {
+  int arg_1 = 0;
+  int res = 0;
+  arg_1 = 1;
+  int const x_19 = arg_1;
+  int const x_15 = atomic_fetch_or_explicit(tint_module_vars.arg_0, x_19, memory_order_relaxed);
+  res = x_15;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicOr_d09248(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_33 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_33, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicOr/workgroup_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicOr/workgroup_u32.spvasm.expected.ir.msl
index 49e8313..7c75031 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicOr/workgroup_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicOr/workgroup_u32.spvasm.expected.ir.msl
@@ -1,9 +1,40 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_uint* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_uint tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicOr
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicOr_5e3d61(tint_module_vars_struct tint_module_vars) {
+  uint arg_1 = 0u;
+  uint res = 0u;
+  arg_1 = 1u;
+  uint const x_18 = arg_1;
+  uint const x_14 = atomic_fetch_or_explicit(tint_module_vars.arg_0, x_18, memory_order_relaxed);
+  res = x_14;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicOr_5e3d61(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_32 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_32, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicStore/storage_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicStore/storage_i32.spvasm.expected.ir.msl
index a33344a..8282660 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicStore/storage_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicStore/storage_i32.spvasm.expected.ir.msl
@@ -1,53 +1,29 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_int arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<i32> @offset(0)
+void atomicStore_d1e9a6(tint_module_vars_struct tint_module_vars) {
+  int arg_1 = 0;
+  arg_1 = 1;
+  int const x_20 = arg_1;
+  atomic_store_explicit((&(*tint_module_vars.sb_rw).arg_0), x_20, memory_order_relaxed);
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicStore_d1e9a6(tint_module_vars);
 }
-
-%atomicStore_d1e9a6 = func():void {
-  $B2: {
-    %arg_1:ptr<function, i32, read_write> = var, 0i
-    store %arg_1, 1i
-    %4:i32 = load %arg_1
-    %x_20:i32 = let %4
-    %6:ptr<storage, atomic<i32>, read_write> = access %sb_rw, 0u
-    %7:void = atomicStore %6, %x_20
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %9:void = call %atomicStore_d1e9a6
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicStore_d1e9a6(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %11:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %13:void = call %atomicStore_d1e9a6
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %15:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicStore/storage_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicStore/storage_u32.spvasm.expected.ir.msl
index d8786c0..51d1c7e 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicStore/storage_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicStore/storage_u32.spvasm.expected.ir.msl
@@ -1,53 +1,29 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_uint arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<u32> @offset(0)
+void atomicStore_cdc29e(tint_module_vars_struct tint_module_vars) {
+  uint arg_1 = 0u;
+  arg_1 = 1u;
+  uint const x_18 = arg_1;
+  atomic_store_explicit((&(*tint_module_vars.sb_rw).arg_0), x_18, memory_order_relaxed);
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicStore_cdc29e(tint_module_vars);
 }
-
-%atomicStore_cdc29e = func():void {
-  $B2: {
-    %arg_1:ptr<function, u32, read_write> = var, 0u
-    store %arg_1, 1u
-    %4:u32 = load %arg_1
-    %x_18:u32 = let %4
-    %6:ptr<storage, atomic<u32>, read_write> = access %sb_rw, 0u
-    %7:void = atomicStore %6, %x_18
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %9:void = call %atomicStore_cdc29e
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicStore_cdc29e(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %11:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %13:void = call %atomicStore_cdc29e
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %15:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicStore/workgroup_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicStore/workgroup_i32.spvasm.expected.ir.msl
index 92c0fdd..7c42615 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicStore/workgroup_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicStore/workgroup_i32.spvasm.expected.ir.msl
@@ -1,9 +1,38 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_int* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_int tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicStore
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicStore_8bea94(tint_module_vars_struct tint_module_vars) {
+  int arg_1 = 0;
+  arg_1 = 1;
+  int const x_19 = arg_1;
+  atomic_store_explicit(tint_module_vars.arg_0, x_19, memory_order_relaxed);
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicStore_8bea94(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_32 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_32, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicStore/workgroup_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicStore/workgroup_u32.spvasm.expected.ir.msl
index 92c0fdd..7c67b38 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicStore/workgroup_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicStore/workgroup_u32.spvasm.expected.ir.msl
@@ -1,9 +1,38 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_uint* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_uint tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicStore
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicStore_726882(tint_module_vars_struct tint_module_vars) {
+  uint arg_1 = 0u;
+  arg_1 = 1u;
+  uint const x_18 = arg_1;
+  atomic_store_explicit(tint_module_vars.arg_0, x_18, memory_order_relaxed);
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicStore_726882(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_31 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_31, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicSub/storage_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicSub/storage_i32.spvasm.expected.ir.msl
index 6b41579..47e31ff 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicSub/storage_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicSub/storage_i32.spvasm.expected.ir.msl
@@ -1,56 +1,31 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_int arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<i32> @offset(0)
+void atomicSub_051100(tint_module_vars_struct tint_module_vars) {
+  int arg_1 = 0;
+  int res = 0;
+  arg_1 = 1;
+  int const x_20 = arg_1;
+  int const x_13 = atomic_fetch_sub_explicit((&(*tint_module_vars.sb_rw).arg_0), x_20, memory_order_relaxed);
+  res = x_13;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicSub_051100(tint_module_vars);
 }
-
-%atomicSub_051100 = func():void {
-  $B2: {
-    %arg_1:ptr<function, i32, read_write> = var, 0i
-    %res:ptr<function, i32, read_write> = var, 0i
-    store %arg_1, 1i
-    %5:i32 = load %arg_1
-    %x_20:i32 = let %5
-    %7:ptr<storage, atomic<i32>, read_write> = access %sb_rw, 0u
-    %8:i32 = atomicSub %7, %x_20
-    %x_13:i32 = let %8
-    store %res, %x_13
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %11:void = call %atomicSub_051100
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicSub_051100(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %13:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %15:void = call %atomicSub_051100
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %17:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicSub/storage_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicSub/storage_u32.spvasm.expected.ir.msl
index a48c41d..1d03833 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicSub/storage_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicSub/storage_u32.spvasm.expected.ir.msl
@@ -1,56 +1,31 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_uint arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<u32> @offset(0)
+void atomicSub_15bfc9(tint_module_vars_struct tint_module_vars) {
+  uint arg_1 = 0u;
+  uint res = 0u;
+  arg_1 = 1u;
+  uint const x_18 = arg_1;
+  uint const x_13 = atomic_fetch_sub_explicit((&(*tint_module_vars.sb_rw).arg_0), x_18, memory_order_relaxed);
+  res = x_13;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicSub_15bfc9(tint_module_vars);
 }
-
-%atomicSub_15bfc9 = func():void {
-  $B2: {
-    %arg_1:ptr<function, u32, read_write> = var, 0u
-    %res:ptr<function, u32, read_write> = var, 0u
-    store %arg_1, 1u
-    %5:u32 = load %arg_1
-    %x_18:u32 = let %5
-    %7:ptr<storage, atomic<u32>, read_write> = access %sb_rw, 0u
-    %8:u32 = atomicSub %7, %x_18
-    %x_13:u32 = let %8
-    store %res, %x_13
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %11:void = call %atomicSub_15bfc9
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicSub_15bfc9(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %13:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %15:void = call %atomicSub_15bfc9
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %17:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicSub/workgroup_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicSub/workgroup_i32.spvasm.expected.ir.msl
index 0c4bcbe..cea6da2 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicSub/workgroup_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicSub/workgroup_i32.spvasm.expected.ir.msl
@@ -1,9 +1,40 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_int* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_int tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicSub
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicSub_77883a(tint_module_vars_struct tint_module_vars) {
+  int arg_1 = 0;
+  int res = 0;
+  arg_1 = 1;
+  int const x_19 = arg_1;
+  int const x_15 = atomic_fetch_sub_explicit(tint_module_vars.arg_0, x_19, memory_order_relaxed);
+  res = x_15;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicSub_77883a(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_33 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_33, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicSub/workgroup_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicSub/workgroup_u32.spvasm.expected.ir.msl
index 0c4bcbe..1550a8a 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicSub/workgroup_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicSub/workgroup_u32.spvasm.expected.ir.msl
@@ -1,9 +1,40 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_uint* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_uint tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicSub
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicSub_0d26c2(tint_module_vars_struct tint_module_vars) {
+  uint arg_1 = 0u;
+  uint res = 0u;
+  arg_1 = 1u;
+  uint const x_18 = arg_1;
+  uint const x_14 = atomic_fetch_sub_explicit(tint_module_vars.arg_0, x_18, memory_order_relaxed);
+  res = x_14;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicSub_0d26c2(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_32 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_32, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicXor/storage_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicXor/storage_i32.spvasm.expected.ir.msl
index e184a49..2551786 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicXor/storage_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicXor/storage_i32.spvasm.expected.ir.msl
@@ -1,56 +1,31 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_int arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<i32> @offset(0)
+void atomicXor_c1b78c(tint_module_vars_struct tint_module_vars) {
+  int arg_1 = 0;
+  int res = 0;
+  arg_1 = 1;
+  int const x_20 = arg_1;
+  int const x_13 = atomic_fetch_xor_explicit((&(*tint_module_vars.sb_rw).arg_0), x_20, memory_order_relaxed);
+  res = x_13;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicXor_c1b78c(tint_module_vars);
 }
-
-%atomicXor_c1b78c = func():void {
-  $B2: {
-    %arg_1:ptr<function, i32, read_write> = var, 0i
-    %res:ptr<function, i32, read_write> = var, 0i
-    store %arg_1, 1i
-    %5:i32 = load %arg_1
-    %x_20:i32 = let %5
-    %7:ptr<storage, atomic<i32>, read_write> = access %sb_rw, 0u
-    %8:i32 = atomicXor %7, %x_20
-    %x_13:i32 = let %8
-    store %res, %x_13
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %11:void = call %atomicXor_c1b78c
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicXor_c1b78c(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %13:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %15:void = call %atomicXor_c1b78c
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %17:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicXor/storage_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicXor/storage_u32.spvasm.expected.ir.msl
index b29898a..c38a141 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicXor/storage_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicXor/storage_u32.spvasm.expected.ir.msl
@@ -1,56 +1,31 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_uint arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<u32> @offset(0)
+void atomicXor_54510e(tint_module_vars_struct tint_module_vars) {
+  uint arg_1 = 0u;
+  uint res = 0u;
+  arg_1 = 1u;
+  uint const x_18 = arg_1;
+  uint const x_13 = atomic_fetch_xor_explicit((&(*tint_module_vars.sb_rw).arg_0), x_18, memory_order_relaxed);
+  res = x_13;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicXor_54510e(tint_module_vars);
 }
-
-%atomicXor_54510e = func():void {
-  $B2: {
-    %arg_1:ptr<function, u32, read_write> = var, 0u
-    %res:ptr<function, u32, read_write> = var, 0u
-    store %arg_1, 1u
-    %5:u32 = load %arg_1
-    %x_18:u32 = let %5
-    %7:ptr<storage, atomic<u32>, read_write> = access %sb_rw, 0u
-    %8:u32 = atomicXor %7, %x_18
-    %x_13:u32 = let %8
-    store %res, %x_13
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %11:void = call %atomicXor_54510e
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicXor_54510e(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %13:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %15:void = call %atomicXor_54510e
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %17:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicXor/workgroup_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicXor/workgroup_i32.spvasm.expected.ir.msl
index 665f64b..2dece42 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicXor/workgroup_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicXor/workgroup_i32.spvasm.expected.ir.msl
@@ -1,9 +1,40 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_int* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_int tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicXor
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicXor_75dc95(tint_module_vars_struct tint_module_vars) {
+  int arg_1 = 0;
+  int res = 0;
+  arg_1 = 1;
+  int const x_19 = arg_1;
+  int const x_15 = atomic_fetch_xor_explicit(tint_module_vars.arg_0, x_19, memory_order_relaxed);
+  res = x_15;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicXor_75dc95(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_33 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_33, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/var/atomicXor/workgroup_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/atomicXor/workgroup_u32.spvasm.expected.ir.msl
index 665f64b..e142db1 100644
--- a/test/tint/builtins/atomics/from_gen/var/atomicXor/workgroup_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/atomicXor/workgroup_u32.spvasm.expected.ir.msl
@@ -1,9 +1,40 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_uint* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_uint tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicXor
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicXor_c8e6be(tint_module_vars_struct tint_module_vars) {
+  uint arg_1 = 0u;
+  uint res = 0u;
+  arg_1 = 1u;
+  uint const x_18 = arg_1;
+  uint const x_14 = atomic_fetch_xor_explicit(tint_module_vars.arg_0, x_18, memory_order_relaxed);
+  res = x_14;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicXor_c8e6be(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_32 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_32, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/var/spvAtomicDecrement/storage_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/spvAtomicDecrement/storage_i32.spvasm.expected.ir.msl
index f87530e..70a1bee 100644
--- a/test/tint/builtins/atomics/from_gen/var/spvAtomicDecrement/storage_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/spvAtomicDecrement/storage_i32.spvasm.expected.ir.msl
@@ -1,54 +1,30 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_int arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<i32> @offset(0)
+void atomicAdd_d32fe4(tint_module_vars_struct tint_module_vars) {
+  int arg_1 = 0;
+  int res = 0;
+  arg_1 = 1;
+  int const x_13 = atomic_fetch_sub_explicit((&(*tint_module_vars.sb_rw).arg_0), 1, memory_order_relaxed);
+  res = x_13;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAdd_d32fe4(tint_module_vars);
 }
-
-%atomicAdd_d32fe4 = func():void {
-  $B2: {
-    %arg_1:ptr<function, i32, read_write> = var, 0i
-    %res:ptr<function, i32, read_write> = var, 0i
-    store %arg_1, 1i
-    %5:ptr<storage, atomic<i32>, read_write> = access %sb_rw, 0u
-    %6:i32 = atomicSub %5, 1i
-    %x_13:i32 = let %6
-    store %res, %x_13
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %9:void = call %atomicAdd_d32fe4
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAdd_d32fe4(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %11:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %13:void = call %atomicAdd_d32fe4
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %15:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/var/spvAtomicDecrement/storage_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/spvAtomicDecrement/storage_u32.spvasm.expected.ir.msl
index d827813..9b8a26e 100644
--- a/test/tint/builtins/atomics/from_gen/var/spvAtomicDecrement/storage_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/spvAtomicDecrement/storage_u32.spvasm.expected.ir.msl
@@ -1,54 +1,30 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_uint arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<u32> @offset(0)
+void atomicAdd_8a199a(tint_module_vars_struct tint_module_vars) {
+  uint arg_1 = 0u;
+  uint res = 0u;
+  arg_1 = 1u;
+  uint const x_13 = atomic_fetch_sub_explicit((&(*tint_module_vars.sb_rw).arg_0), 1u, memory_order_relaxed);
+  res = x_13;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAdd_8a199a(tint_module_vars);
 }
-
-%atomicAdd_8a199a = func():void {
-  $B2: {
-    %arg_1:ptr<function, u32, read_write> = var, 0u
-    %res:ptr<function, u32, read_write> = var, 0u
-    store %arg_1, 1u
-    %5:ptr<storage, atomic<u32>, read_write> = access %sb_rw, 0u
-    %6:u32 = atomicSub %5, 1u
-    %x_13:u32 = let %6
-    store %res, %x_13
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %9:void = call %atomicAdd_8a199a
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAdd_8a199a(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %11:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %13:void = call %atomicAdd_8a199a
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %15:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/var/spvAtomicDecrement/workgroup_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/spvAtomicDecrement/workgroup_i32.spvasm.expected.ir.msl
index 0c4bcbe..327a061 100644
--- a/test/tint/builtins/atomics/from_gen/var/spvAtomicDecrement/workgroup_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/spvAtomicDecrement/workgroup_i32.spvasm.expected.ir.msl
@@ -1,9 +1,39 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_int* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_int tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicSub
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicAdd_794055(tint_module_vars_struct tint_module_vars) {
+  int arg_1 = 0;
+  int res = 0;
+  arg_1 = 1;
+  int const x_15 = atomic_fetch_sub_explicit(tint_module_vars.arg_0, 1, memory_order_relaxed);
+  res = x_15;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicAdd_794055(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_33 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_33, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/var/spvAtomicDecrement/workgroup_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/spvAtomicDecrement/workgroup_u32.spvasm.expected.ir.msl
index 0c4bcbe..9ddb2b6 100644
--- a/test/tint/builtins/atomics/from_gen/var/spvAtomicDecrement/workgroup_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/spvAtomicDecrement/workgroup_u32.spvasm.expected.ir.msl
@@ -1,9 +1,39 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_uint* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_uint tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicSub
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicAdd_d5db1d(tint_module_vars_struct tint_module_vars) {
+  uint arg_1 = 0u;
+  uint res = 0u;
+  arg_1 = 1u;
+  uint const x_14 = atomic_fetch_sub_explicit(tint_module_vars.arg_0, 1u, memory_order_relaxed);
+  res = x_14;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicAdd_d5db1d(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_32 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_32, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/var/spvAtomicIncrement/storage_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/spvAtomicIncrement/storage_i32.spvasm.expected.ir.msl
index 006c1b4..efc10ec 100644
--- a/test/tint/builtins/atomics/from_gen/var/spvAtomicIncrement/storage_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/spvAtomicIncrement/storage_i32.spvasm.expected.ir.msl
@@ -1,54 +1,30 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_int arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<i32> @offset(0)
+void atomicAdd_d32fe4(tint_module_vars_struct tint_module_vars) {
+  int arg_1 = 0;
+  int res = 0;
+  arg_1 = 1;
+  int const x_13 = atomic_fetch_add_explicit((&(*tint_module_vars.sb_rw).arg_0), 1, memory_order_relaxed);
+  res = x_13;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAdd_d32fe4(tint_module_vars);
 }
-
-%atomicAdd_d32fe4 = func():void {
-  $B2: {
-    %arg_1:ptr<function, i32, read_write> = var, 0i
-    %res:ptr<function, i32, read_write> = var, 0i
-    store %arg_1, 1i
-    %5:ptr<storage, atomic<i32>, read_write> = access %sb_rw, 0u
-    %6:i32 = atomicAdd %5, 1i
-    %x_13:i32 = let %6
-    store %res, %x_13
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %9:void = call %atomicAdd_d32fe4
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAdd_d32fe4(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %11:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %13:void = call %atomicAdd_d32fe4
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %15:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/var/spvAtomicIncrement/storage_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/spvAtomicIncrement/storage_u32.spvasm.expected.ir.msl
index 0275a62..e75985d 100644
--- a/test/tint/builtins/atomics/from_gen/var/spvAtomicIncrement/storage_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/spvAtomicIncrement/storage_u32.spvasm.expected.ir.msl
@@ -1,54 +1,30 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW_atomic {
+  atomic_uint arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW_atomic* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW_atomic = struct @align(4) {
-  arg_0:atomic<u32> @offset(0)
+void atomicAdd_8a199a(tint_module_vars_struct tint_module_vars) {
+  uint arg_1 = 0u;
+  uint res = 0u;
+  arg_1 = 1u;
+  uint const x_13 = atomic_fetch_add_explicit((&(*tint_module_vars.sb_rw).arg_0), 1u, memory_order_relaxed);
+  res = x_13;
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW_atomic, read_write> = var @binding_point(0, 0)
+void fragment_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAdd_8a199a(tint_module_vars);
 }
-
-%atomicAdd_8a199a = func():void {
-  $B2: {
-    %arg_1:ptr<function, u32, read_write> = var, 0u
-    %res:ptr<function, u32, read_write> = var, 0u
-    store %arg_1, 1u
-    %5:ptr<storage, atomic<u32>, read_write> = access %sb_rw, 0u
-    %6:u32 = atomicAdd %5, 1u
-    %x_13:u32 = let %6
-    store %res, %x_13
-    ret
-  }
+fragment void fragment_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  fragment_main_1(tint_module_vars);
 }
-%fragment_main_1 = func():void {
-  $B3: {
-    %9:void = call %atomicAdd_8a199a
-    ret
-  }
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  atomicAdd_8a199a(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B4: {
-    %11:void = call %fragment_main_1
-    ret
-  }
+kernel void compute_main(device SB_RW_atomic* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  compute_main_1(tint_module_vars);
 }
-%compute_main_1 = func():void {
-  $B5: {
-    %13:void = call %atomicAdd_8a199a
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B6: {
-    %15:void = call %compute_main_1
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/atomics/from_gen/var/spvAtomicIncrement/workgroup_i32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/spvAtomicIncrement/workgroup_i32.spvasm.expected.ir.msl
index f7dc0d0..43c16e8 100644
--- a/test/tint/builtins/atomics/from_gen/var/spvAtomicIncrement/workgroup_i32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/spvAtomicIncrement/workgroup_i32.spvasm.expected.ir.msl
@@ -1,9 +1,39 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_int* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_int tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicAdd
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicAdd_794055(tint_module_vars_struct tint_module_vars) {
+  int arg_1 = 0;
+  int res = 0;
+  arg_1 = 1;
+  int const x_15 = atomic_fetch_add_explicit(tint_module_vars.arg_0, 1, memory_order_relaxed);
+  res = x_15;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicAdd_794055(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_33 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_33, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/atomics/from_gen/var/spvAtomicIncrement/workgroup_u32.spvasm.expected.ir.msl b/test/tint/builtins/atomics/from_gen/var/spvAtomicIncrement/workgroup_u32.spvasm.expected.ir.msl
index f7dc0d0..4b964cb 100644
--- a/test/tint/builtins/atomics/from_gen/var/spvAtomicIncrement/workgroup_u32.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomics/from_gen/var/spvAtomicIncrement/workgroup_u32.spvasm.expected.ir.msl
@@ -1,9 +1,39 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  thread uint* local_invocation_index_1;
+  threadgroup atomic_uint* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_uint tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicAdd
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicAdd_d5db1d(tint_module_vars_struct tint_module_vars) {
+  uint arg_1 = 0u;
+  uint res = 0u;
+  arg_1 = 1u;
+  uint const x_14 = atomic_fetch_add_explicit(tint_module_vars.arg_0, 1u, memory_order_relaxed);
+  res = x_14;
+}
+void compute_main_inner(uint local_invocation_index_2, tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicAdd_d5db1d(tint_module_vars);
+}
+void compute_main_1(tint_module_vars_struct tint_module_vars) {
+  uint const x_32 = (*tint_module_vars.local_invocation_index_1);
+  compute_main_inner(x_32, tint_module_vars);
+}
+void compute_main_inner_1(uint local_invocation_index_1_param, tint_module_vars_struct tint_module_vars) {
+  if ((local_invocation_index_1_param == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  (*tint_module_vars.local_invocation_index_1) = local_invocation_index_1_param;
+  compute_main_1(tint_module_vars);
+}
+kernel void compute_main(uint local_invocation_index_1_param [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  thread uint local_invocation_index_1 = 0u;
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.local_invocation_index_1=(&local_invocation_index_1), .arg_0=(&(*v).tint_symbol)};
+  compute_main_inner_1(local_invocation_index_1_param, tint_module_vars);
+}
diff --git a/test/tint/builtins/gen/literal/atomicStore/726882.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/atomicStore/726882.wgsl.expected.ir.msl
index 92c0fdd..02bd3b8 100644
--- a/test/tint/builtins/gen/literal/atomicStore/726882.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/atomicStore/726882.wgsl.expected.ir.msl
@@ -1,9 +1,23 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  threadgroup atomic_uint* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_uint tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicStore
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicStore_726882(tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 1u, memory_order_relaxed);
+}
+void compute_main_inner(uint tint_local_index, tint_module_vars_struct tint_module_vars) {
+  if ((tint_local_index == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicStore_726882(tint_module_vars);
+}
+kernel void compute_main(uint tint_local_index [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=(&(*v).tint_symbol)};
+  compute_main_inner(tint_local_index, tint_module_vars);
+}
diff --git a/test/tint/builtins/gen/literal/atomicStore/8bea94.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/atomicStore/8bea94.wgsl.expected.ir.msl
index 92c0fdd..e56aaa9 100644
--- a/test/tint/builtins/gen/literal/atomicStore/8bea94.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/atomicStore/8bea94.wgsl.expected.ir.msl
@@ -1,9 +1,23 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  threadgroup atomic_int* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_int tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicStore
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicStore_8bea94(tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit(tint_module_vars.arg_0, 1, memory_order_relaxed);
+}
+void compute_main_inner(uint tint_local_index, tint_module_vars_struct tint_module_vars) {
+  if ((tint_local_index == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicStore_8bea94(tint_module_vars);
+}
+kernel void compute_main(uint tint_local_index [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=(&(*v).tint_symbol)};
+  compute_main_inner(tint_local_index, tint_module_vars);
+}
diff --git a/test/tint/builtins/gen/literal/atomicStore/cdc29e.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/atomicStore/cdc29e.wgsl.expected.ir.msl
index 4d4d962..b897dc9 100644
--- a/test/tint/builtins/gen/literal/atomicStore/cdc29e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/atomicStore/cdc29e.wgsl.expected.ir.msl
@@ -1,37 +1,20 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW {
+  atomic_uint arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW = struct @align(4) {
-  arg_0:atomic<u32> @offset(0)
+void atomicStore_cdc29e(tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit((&(*tint_module_vars.sb_rw).arg_0), 1u, memory_order_relaxed);
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW, read_write> = var @binding_point(0, 0)
+fragment void fragment_main(device SB_RW* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  atomicStore_cdc29e(tint_module_vars);
 }
-
-%atomicStore_cdc29e = func():void {
-  $B2: {
-    %3:ptr<storage, atomic<u32>, read_write> = access %sb_rw, 0u
-    %4:void = atomicStore %3, 1u
-    ret
-  }
+kernel void compute_main(device SB_RW* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  atomicStore_cdc29e(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B3: {
-    %6:void = call %atomicStore_cdc29e
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B4: {
-    %8:void = call %atomicStore_cdc29e
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/gen/literal/atomicStore/d1e9a6.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/atomicStore/d1e9a6.wgsl.expected.ir.msl
index 1e78e33..5cd7716 100644
--- a/test/tint/builtins/gen/literal/atomicStore/d1e9a6.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/atomicStore/d1e9a6.wgsl.expected.ir.msl
@@ -1,37 +1,20 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW {
+  atomic_int arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW = struct @align(4) {
-  arg_0:atomic<i32> @offset(0)
+void atomicStore_d1e9a6(tint_module_vars_struct tint_module_vars) {
+  atomic_store_explicit((&(*tint_module_vars.sb_rw).arg_0), 1, memory_order_relaxed);
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW, read_write> = var @binding_point(0, 0)
+fragment void fragment_main(device SB_RW* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  atomicStore_d1e9a6(tint_module_vars);
 }
-
-%atomicStore_d1e9a6 = func():void {
-  $B2: {
-    %3:ptr<storage, atomic<i32>, read_write> = access %sb_rw, 0u
-    %4:void = atomicStore %3, 1i
-    ret
-  }
+kernel void compute_main(device SB_RW* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  atomicStore_d1e9a6(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B3: {
-    %6:void = call %atomicStore_d1e9a6
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B4: {
-    %8:void = call %atomicStore_d1e9a6
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/gen/var/atomicStore/726882.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/atomicStore/726882.wgsl.expected.ir.msl
index 92c0fdd..1972925 100644
--- a/test/tint/builtins/gen/var/atomicStore/726882.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/atomicStore/726882.wgsl.expected.ir.msl
@@ -1,9 +1,24 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  threadgroup atomic_uint* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_uint tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicStore
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicStore_726882(tint_module_vars_struct tint_module_vars) {
+  uint arg_1 = 1u;
+  atomic_store_explicit(tint_module_vars.arg_0, arg_1, memory_order_relaxed);
+}
+void compute_main_inner(uint tint_local_index, tint_module_vars_struct tint_module_vars) {
+  if ((tint_local_index == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0u, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicStore_726882(tint_module_vars);
+}
+kernel void compute_main(uint tint_local_index [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=(&(*v).tint_symbol)};
+  compute_main_inner(tint_local_index, tint_module_vars);
+}
diff --git a/test/tint/builtins/gen/var/atomicStore/8bea94.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/atomicStore/8bea94.wgsl.expected.ir.msl
index 92c0fdd..857469c 100644
--- a/test/tint/builtins/gen/var/atomicStore/8bea94.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/atomicStore/8bea94.wgsl.expected.ir.msl
@@ -1,9 +1,24 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct tint_module_vars_struct {
+  threadgroup atomic_int* arg_0;
+};
+struct tint_symbol_1 {
+  atomic_int tint_symbol;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:924 internal compiler error: TINT_UNREACHABLE unhandled: atomicStore
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
+void atomicStore_8bea94(tint_module_vars_struct tint_module_vars) {
+  int arg_1 = 1;
+  atomic_store_explicit(tint_module_vars.arg_0, arg_1, memory_order_relaxed);
+}
+void compute_main_inner(uint tint_local_index, tint_module_vars_struct tint_module_vars) {
+  if ((tint_local_index == 0u)) {
+    atomic_store_explicit(tint_module_vars.arg_0, 0, memory_order_relaxed);
+  }
+  threadgroup_barrier(mem_flags::mem_threadgroup);
+  atomicStore_8bea94(tint_module_vars);
+}
+kernel void compute_main(uint tint_local_index [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=(&(*v).tint_symbol)};
+  compute_main_inner(tint_local_index, tint_module_vars);
+}
diff --git a/test/tint/builtins/gen/var/atomicStore/cdc29e.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/atomicStore/cdc29e.wgsl.expected.ir.msl
index c1a5cdb..0380ecf 100644
--- a/test/tint/builtins/gen/var/atomicStore/cdc29e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/atomicStore/cdc29e.wgsl.expected.ir.msl
@@ -1,39 +1,21 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW {
+  atomic_uint arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW = struct @align(4) {
-  arg_0:atomic<u32> @offset(0)
+void atomicStore_cdc29e(tint_module_vars_struct tint_module_vars) {
+  uint arg_1 = 1u;
+  atomic_store_explicit((&(*tint_module_vars.sb_rw).arg_0), arg_1, memory_order_relaxed);
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW, read_write> = var @binding_point(0, 0)
+fragment void fragment_main(device SB_RW* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  atomicStore_cdc29e(tint_module_vars);
 }
-
-%atomicStore_cdc29e = func():void {
-  $B2: {
-    %arg_1:ptr<function, u32, read_write> = var, 1u
-    %4:ptr<storage, atomic<u32>, read_write> = access %sb_rw, 0u
-    %5:u32 = load %arg_1
-    %6:void = atomicStore %4, %5
-    ret
-  }
+kernel void compute_main(device SB_RW* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  atomicStore_cdc29e(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B3: {
-    %8:void = call %atomicStore_cdc29e
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B4: {
-    %10:void = call %atomicStore_cdc29e
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/builtins/gen/var/atomicStore/d1e9a6.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/atomicStore/d1e9a6.wgsl.expected.ir.msl
index 9e419f8..0333481 100644
--- a/test/tint/builtins/gen/var/atomicStore/d1e9a6.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/atomicStore/d1e9a6.wgsl.expected.ir.msl
@@ -1,39 +1,21 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
+struct SB_RW {
+  atomic_int arg_0;
+};
+struct tint_module_vars_struct {
+  device SB_RW* sb_rw;
+};
 
-../../src/tint/lang/msl/writer/printer/printer.cc:500 internal compiler error: SB_RW = struct @align(4) {
-  arg_0:atomic<i32> @offset(0)
+void atomicStore_d1e9a6(tint_module_vars_struct tint_module_vars) {
+  int arg_1 = 1;
+  atomic_store_explicit((&(*tint_module_vars.sb_rw).arg_0), arg_1, memory_order_relaxed);
 }
-
-$B1: {  # root
-  %sb_rw:ptr<storage, SB_RW, read_write> = var @binding_point(0, 0)
+fragment void fragment_main(device SB_RW* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  atomicStore_d1e9a6(tint_module_vars);
 }
-
-%atomicStore_d1e9a6 = func():void {
-  $B2: {
-    %arg_1:ptr<function, i32, read_write> = var, 1i
-    %4:ptr<storage, atomic<i32>, read_write> = access %sb_rw, 0u
-    %5:i32 = load %arg_1
-    %6:void = atomicStore %4, %5
-    ret
-  }
+kernel void compute_main(device SB_RW* sb_rw [[buffer(0)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb_rw=sb_rw};
+  atomicStore_d1e9a6(tint_module_vars);
 }
-%fragment_main = @fragment func():void {
-  $B3: {
-    %8:void = call %atomicStore_d1e9a6
-    ret
-  }
-}
-%compute_main = @compute @workgroup_size(1, 1, 1) func():void {
-  $B4: {
-    %10:void = call %atomicStore_d1e9a6
-    ret
-  }
-}
-
-unhandled variable address space
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************